2016-08-22 5 views
1

У меня были проблемы с Task, которые я использовал ContinueWith. В обратном вызове я не наблюдал/не обрабатывал Exception при первой ошибке. Я узнал, что происходит в этом случае здесь:
Proper way to use .ContinueWith for TasksКто ждет задание по умолчанию?

Имей в виде, что, если ваши собственные продолжения не соблюдают исключения, человек, который ждет от этого общего рабочего процесса полного собираемся чтобы наблюдать это.

Что заставило меня задаться вопросом:
Кто официант Task, не ждали?
Кто ждёт Task по умолчанию?

Например:

public int HowOldAmI() 
{ 
    Task t = Task.Run(async() => { 
      await Task.Delay(5000); 
      throw new Exception("Something happened"); 
    }); 
    return 42; 
} 

В этом случае кто ждет Task?

+3

Ничего, в случае, если вы показали. Ничто «неявно» не ожидает завершения задачи - если вы решите создать задачу и не дождаться ее, любые исключения перейдут к незаметному обработчику исключений. –

+0

Хорошо спасибо @ JonSkeet. Описанный где-то обработчик исключений _unobserved? Причина, по которой я спрашиваю, заключается в том, что моя библиотека отчетов об авариях ловит эти исключения, хотя реального сбоя не происходит, поэтому я пытаюсь правильно обрабатывать исключения, чтобы они не отображались в моих отчетах о сбоях. –

+1

См. Ответ от Andrew ... –

ответ

2

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

Существует также событие, которое помогает с незаметными исключениями (например, чтобы они как минимум регистрировались где-то): TaskScheduler.UnobservedTaskException.

Смотрите также обсуждение в этом вопросе: Unobserved Task exceptions in .NET 4.5 still crash app

+0

Хорошо спасибо. Таким образом, будет вызываться обработчик _UnobservedTaskException_, даже если я продолжу свою первую 'Task t' с' t.ContinueWith ((previousTask) => {/ * Code, который не соблюдает Исключение * /}); '? –

+1

Да, точно. Вам нужно будет получить доступ к свойствам «Результат» или «Исключение», или ждать, пока его результат не будет «наблюдаемым». В противном случае он будет передан на это событие. –