2017-02-17 7 views
1

У меня есть приложение C#, которое выполняет метод, который возвращает Task. В этом случае я пытаюсь показать окно сообщения, содержащее сведения об исключении, если вызываемый метод выдает исключение.Задание Исключение Null в цепочке C# Продолжение задачи

Если я называю это так, я могу видеть исключение штраф в task.Exception:

MyClass.MyAsyncMethod(cancellationToken) 
     .LogExceptions() 
     .ContinueWith(task => { 
      MessageBox.Show(task.Exception); 
     }, cancellationToken, TaskContinuationOptions.NotOnRanToCompletion, TaskScheduler.Default); 

Однако, если добавить OnlyOnRanToCompletion продолжение, task.Exception в NotOnRanToCompletion продолжение становится нулевым:

MyClass.MyAsyncMethod(cancellationToken) 
     .LogExceptions() 
     .ContinueWith(task => { 
      Log.Info("Executed"); 
     }, cancellationToken, TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.Default) 
     .ContinueWith(task => { 
      MessageBox.Show(task.Exception); 
     }, cancellationToken, TaskContinuationOptions.NotOnRanToCompletion, TaskScheduler.Default); 

Код в OnlyOnranToCompletion продолжение не исполнено, но код в NotOnRanToCompletion продолжен и task.Exception является n Улла. Почему это происходит?

Примечание: Я не могу использовать C# >= 5.0 функции, такие как async или await. Я также могу обойти это, имея все это под одним методом продолжения None, который проверяет параметр исключения задачи и определяет, произошло ли исключение. Тем не менее, меня интересует ПОЧЕМУ вышеуказанное поведение имеет место.


Это называется метод:

public Task<bool> MyAsyncMethod(CancellationToken cancellationToken) 
{ 
    return Task<bool>.Factory.StartNew(() => 
    { 
     ... 

     try 
     { 
      var response = request.GetResponse(); 
      if (response.StatusCode != HttpStatusCode.OK) 
       throw new Exception("Invalid response status code: " + response.StatusCode); 
     } 
     catch (Exception ex) 
     { 
      Logger.Error("Request failed", ex)); 
      throw; 
     } 
    }, cancellationToken, TaskCreationOptions.None, TaskScheduler.Default); 
} 
+1

Обратите внимание, что тот факт, что обработка ошибок является настолько сложной и утомительной, является большой причиной, по которой добавлен 'await', так как он * значительно упрощает правильную обработку ошибок. – Servy

+0

Согласен, хотя в моем случае обновление до более новой версии невозможно. –

ответ

4

Там не исключение, потому что в Task, что она является продолжением не сгенерирует исключение. Task будет продолжен (предыдущий вызов ContinueWith).

Если вы хотите обрабатывать как ошибку, так и случай без ошибок, вам, вероятно, лучше просто иметь одно продолжение и проверять, было ли оно успешным в этом продолжении, а не использовать варианты продолжения. В качестве альтернативы вы можете сохранить Task из фактической работы, которую вы делаете, и добавить оба продолжения в качестве продолжения к этому Task, вместо того, чтобы одно продолжение было продолжением другого.

+0

Теперь это имеет смысл. Спасибо! –

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