Ответ 1
Вы описываете поведение, поскольку оно было в .NET 4, но вам будет сложно заставить сборку мусора и фактически наблюдать за этим поведением. Следующая цитата из отличная статья Стивена Туба по этому вопросу должна сделать еще более ясным:
Задачи отслеживают, было ли необработанное исключение "наблюдаемый." В этом контексте "наблюдаемый" означает, что код присоединился с Задачей в некотором роде, чтобы, по крайней мере, узнать о исключение. Это может вызвать Wait/WaitAll в Задаче. Это может быть проверено свойство Tasks Exception после выполнения задачи завершено. Или это может быть свойство Tasks Result. Если Задача видит, что ее исключение наблюдалось в некотором роде, жизнь хороша. Если, однако, удалены все ссылки на задачу (что делает задачу доступной для сбора мусора), и если ее исключение пока не наблюдается, Задача знает, что ее исключение никогда не будет наблюдаться. В этом случае задача использует преимущества финализация и использует вспомогательный объект для распространения необработанного исключение в потоке финализатора. С описанным поведением ранее это исключение в потоке финализатора будет обрабатываться без обработки и вызывать стандартную необработанную логику исключения, которая должна регистрировать выдает и разбивает процесс.
Он также предложил два полезных метода расширения для обработки исключений в задачах "огонь и забвение": один игнорирует исключение, а другой немедленно разрушает процесс:
public static Task IgnoreExceptions(this Task task)
{
task.ContinueWith(c => { var ignored = c.Exception; },
TaskContinuationOptions.OnlyOnFaulted |
TaskContinuationOptions.ExecuteSynchronously |
TaskContinuationOptions.DetachedFromParent);
return task;
}
public static Task FailFastOnException(this Task task)
{
task.ContinueWith(c => Environment.FailFast("Task faulted", c.Exception),
TaskContinuationOptions.OnlyOnFaulted |
TaskContinuationOptions.ExecuteSynchronously |
TaskContinuationOptions.DetachedFromParent);
return task;
}
В .NET 4.5 поведение по умолчанию изменилось. Опять же, цитата из еще одной статьи Стивена Тубо по этому вопросу (спасибо mike z за то, что привлекла мое внимание в комментариях):
Чтобы разработчики могли писать асинхронный код на основе Задачи .NET 4.5 изменяет поведение исключений по умолчанию для ненаблюдаемых исключения. Хотя незаметные исключения будут по-прежнему вызывать Событие UnobservedTaskException, которое должно быть поднято (не делать этого, было бы изменение), процесс по умолчанию не будет аварийно завершен. Скорее, исключение в конечном итоге будет съедено после того, как событие будет поднято, независимо от того, соблюдает ли обработчик события исключение. Эта поведение может быть настроено, однако.