Задание. Заблокированные и ненаблюдаемые исключения - программирование
Подтвердить что ты не робот

Задание. Заблокированные и ненаблюдаемые исключения

Скажем, у меня три задачи: a, b и c. Все три гарантированно генерируют исключение в случайное время между 1 и 5 секундами. Затем я пишу следующий код:

await Task.WhenAny(a, b, c);

В конечном итоге это приведет к исключению из того, что было раньше. Поскольку здесь нет try...catch, это исключение превратится в какое-то другое место в моем коде.

Что происходит, когда оставшиеся две задачи вызывают исключение? Не являются ли эти незаметные исключения, которые приведут к уничтожению всего процесса? Означает ли это, что единственный способ использования WhenAny находится внутри блока try...catch, а затем каким-то образом наблюдать остальные две задачи, прежде чем продолжить?

Последующее наблюдение:. Я бы хотел, чтобы ответ применялся как к .NET 4.5, так и к .NET 4.0 с помощью пакета асинхронного таргетинга (хотя, очевидно, с использованием TaskEx.WhenAny в этом случае).

4b9b3361

Ответ 1

Что происходит, когда остальные две задачи вызывают исключение?

Те Task завершатся в неисправном состоянии.

Не являются ли эти незаметные исключения, которые приведут к уничтожению всего процесса?

Не больше.

В .NET 4.0 Task деструктор будет проходить его ненаблюдаемое исключение TaskScheduler.UnobservedTaskException, который бы завершить процесс, если необработанные.

В .NET 4.5 это поведение

Ответ 2

Да, остальные исключения задачи остаются незаметными. Pre.NET 4.5 вы обязаны их соблюдать (не знаете, как ситуация на .NET 4.5, но она изменилась).

Обычно я пишу для себя вспомогательный метод для таких задач, как:

    public static void IgnoreUnobservedExceptions(this Task task)
    {
        if (task.IsCompleted)
        {
            if (task.IsFaulted)
            {
                var dummy = task.Exception;
            }
            return;
        }

        task.ContinueWith(t =>
            {
                var dummy = t.Exception;
            }, TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.ExecuteSynchronously);
    }

Возможно, вы захотите включить ведение журнала в производственных приложениях.