Я вижу две опции, которые можно использовать для целей централизации обработки исключений в TPL:
1. Использование события ненаблюдаемого исключения задачи из планировщика задач.
2. Использование продолжений для задач с ошибочным состоянием.
Использование события исключения ненаблюдаемой задачи в планировщике задач.
В планировщике задач есть событие UnobservedTaskException, на которое вы можете подписаться, используя оператор + =.
- Примечание 1. В теле обработчика необходимо выполнить вызов SetObserved () для аргумента UnobservedTaskExceptionEventArgs, чтобы уведомить планировщик об обработке исключения.
- Примечание 2: Обработчик вызывается, когда задачи собраны сборщиком мусора.
- Примечание 3: Если вы будете ждать задания, вы все равно будете вынуждены защищать ожидание блоком try / catch.
- Примечание 4: Политика по умолчанию для необработанных исключений задач в .Net 4.0 и 4.5 отличается.
Резюме: Этот подход хорош для задач запуска и забывания и для отлова исключений, вышедших из вашей политики централизованной обработки исключений.
Использование продолжений для задач с ошибочным состоянием.
С TPL вы можете прикрепить действия к Задаче, используя метод ContinueWith (), который принимает присоединение действия и опцию продолжения. Это действие будет вызвано после завершения задачи и только в случаях, указанных опцией. В частности:
t.ContinueWith(c => { /* exception handling code */ },
TaskContinuationOptions.OnlyOnFaulted);
устанавливает продолжение с кодом обработки исключений в задачу t. Этот код будет работать только в том случае, если задача t была прервана из-за необработанного исключения.
- Примечание 1: Получить значение исключения в коде обработки исключений. В противном случае это будет пузыриться.
- Примечание 2: Код обработки исключений будет вызываться сразу после завершения задачи.
- Примечание 3: Если исключение было получено в коде обработки исключений, оно будет считаться обработанным, блок try / catch при ожидании задачи не сможет его перехватить.
Я думаю, что для централизованной обработки исключений будет лучше использовать пользовательские Задачи, унаследованные от Задачи, с обработчиком исключений, добавленным через продолжение. И сопровождайте этот подход, используя событие «Незаметное исключение задач» в Планировщике задач, чтобы перехватывать попытки использовать ненастроенные задачи.