2016-06-01 9 views
2

При вызове await RunAsync(); по нижеследующему коду я ожидаю продолжение с TaskContinuationOptions.OnlyRanToCompletion продолжением для запуска, однако вызывается вызванное продолжение OnlyOnCanceled (что дает отладочный вывод «Задача отменена»).Почему вызов OnlyOnCanceled называется?

Почему?

private static async Task RunAsync() 
{ 
    try 
    { 
     await Task.Run(() => DoWork()) 
      .ContinueWith(
       (t) => 
       { 
        if (t?.Exception != null) 
        { 
         throw t.Exception; 
        } 
       }, TaskContinuationOptions.OnlyOnFaulted 
      ).ContinueWith(
       (t) => 
       { 
        Debug.WriteLine("Task canceled."); 
       }, TaskContinuationOptions.OnlyOnCanceled 
      ).ContinueWith(
       (t) => 
       { 
        Debug.WriteLine("Task completed."); 
       }, TaskContinuationOptions.OnlyOnRanToCompletion); 

    } 
    catch (Exception ex) 
    { 
     Debug.WriteLine(ex.Message); 
    } 
} 

private static void DoWork() 
{ 
    Thread.Sleep(1000); 

} 

ответ

4

Вы связываете свои действия неправильно.

Вместо добавления трех продолжений к «основной» задаче вы добавляете продолжение в продолжение продолжения. Когда основные задачи заканчиваются без ошибок, продолжение OnlyOnFaulted будет отменено, что приведет к продолжению продолжения OnlyOnCanceled, которое вы неправильно подключили к продолжению OnlyOnFaulted вместо основной задачи. И тогда лучшая часть - это означает, что второе продолжение закончено правильно, и поскольку вы подключили свое последнее продолжение во втором продолжении, окончательное продолжение также выполняется, поэтому полный вывод «Задача отменена. Завершенная задача». :)

Не очевидно, что вы ожидаете быть правильным выходом. Почему вы используете продолжение в первую очередь? await обрабатывает это для вас гораздо приятнее, чем вы можете когда-либо делать вручную. Смешивание await и ContinueWith редко является хорошей идеей :) Вы пытаетесь сделать await главной задачей (если не выбрано исключение)? Или одно из продолжений? Или просто продолжение OnlyOnRanToCompletion (это то, что вы делаете прямо сейчас, и он никогда не будет работать так, как вы ожидаете, что он будет работать)? Что, если это продолжение никогда не получится запустить?

 Смежные вопросы

  • Нет связанных вопросов^_^