У меня есть Task
, который работает асинхронно и обрабатывает исключения, используя продолжение задачи task.ContinueWith(t => ..., CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, taskScheduler)
.
Это прекрасно работает для обработки исключений, которые я знаю, как обрабатывать (например, WebException
), но что, если выдается что-то вроде NullReferenceException
, которое я не могу обработать правильно?
Я хочу иметь возможность обрабатывать его, используя необработанный обработчик исключений AppDomain (который в нашем случае регистрирует ошибку, выскакивает диалоговое окно с уведомлением пользователя и выходит из приложения), но до сих пор я не нашел хорошего способа сделать это.
Простое перебрасывание исключения из продолжения приводит к тому, что обработчик необработанного исключения вызывается при завершении задачи (поскольку переброшенное исключение не наблюдается). Это не очень хорошо, потому что могут пройти секунды или даже минуты после того, как я узнаю, что приложение должно аварийно завершиться.
Вызов Environment.FailFast()
приводит к сбою приложения, но не вызывает необработанный обработчик исключений.
Вызов Thread.CurrentThread.Abort()
вызывает обработчик необработанного исключения, но отображает только информацию / трассировку стека из ThreadAbortException
. Кроме того, использование этого метода кажется плохой идеей.
Вызов Application.OnThreadException()
фактически делает именно то, что я хочу, за исключением того, что он требует ссылки System.Windows.Forms
и обработки Application.ThreadException
, которая не будет работать, например, со службой без пользовательского интерфейса.
Звонить по номеру task.Wait()
не имеет смысла, потому что в нашем случае это некуда звонить. Если задача выполнена успешно, результат обрабатывается с использованием продолжения успеха, если он терпит неудачу, вызывается продолжение исключения, и мы не можем заблокировать поток, создающий задачу (в этом весь смысл задачи).
Я мог бы вызывать обработчик необработанных исключений напрямую, за исключением того, что по крайней мере в одном случае потребовалось бы добавить зависимость, которую я не хочу добавлять в свое приложение.
Мне не хватает очевидного способа сделать это?