Когда ожидаемый метод async
генерирует исключение, это исключение где-то сохраняется, и его создание задерживается. В приложении WinForms или WPF он использует SynchronizationContext.Current
для сообщения об исключении. Однако, в т.ч. консольное приложение, оно генерирует исключение в пуле потоков и останавливает приложение.
Как предотвратить прекращение работы приложения из-за исключений, вызванных методом async
?
ИЗМЕНИТЬ:
По-видимому, проблема, которую я описываю, связана с тем, что у меня есть void
async
методов. Смотрите комментарии.
void
возвращает значение. Это причина по возможности избегать использования методовasync void
. - person svick   schedule 07.09.2012async void
приводят к детерминированному поведению; вызов функции, возвращающейTask
, которая приводит к исключению, и не ожидая выполнения задачи, вызовет событиеUnobservedTaskException
в какой-то полуслучайный момент в будущем, когда запустится сборщик мусора, и если это ничего не даст, программа продолжит работу, как будто все в порядке . Проблема не в методахasync void
, они просто раскрывают реальную проблему. Если вы не вызываете функцию, возвращающуюTask
, из методаasync
, велика вероятность, что вы делаете что-то не так. - person   schedule 07.09.2012UnobservedTaskException
не является проблемой? - person Pieter van Ginkel   schedule 07.09.2012async Task
охватывает естественно недетерминированный характер асинхронного программирования. Сasync void
вы все равно получите исключение в какой-то полуслучайный момент в будущем, которое (обычно) передается непосредственно в ваш основной цикл. Я думаю, что код будет чище, если вы используетеasync Task
и убедитесь, что ониawait
ed. ИМО. :) - person Stephen Cleary   schedule 07.09.2012async void
наблюдают за исключением, отправляя его в контекст синхронизации.async void f() { await g(); }
в порядке.void f() { var task = g(); /* ignore task */ }
нет. - person   schedule 07.09.2012async void
. Я думаю, вы имеете в виду, что один метод должен быть как можно выше, все остальные должны просто возвращать задачу. Если да, то конечно, тут не поспоришь. - person   schedule 07.09.2012async void
. У вас будет один, если вам нужен обработчик событийasync
(обычно в приложениях пользовательского интерфейса), но не иначе. ASP.NET WebAPI и MVC предоставляют вам большинство точек входа верхнего уровня какasync Task
. Для ситуации оператора (консольные приложения) я по-прежнему предпочитаюasync Task
async void
. - person Stephen Cleary   schedule 07.09.2012async void
в своем собственном коде. Не знал, что такое существует, прикольно, спасибо за информацию. FWIW, что я делаю в своем собственном коде, так это использую методasync void
, который не делает ничего, кроме ожидания другой задачи, перехватывая определенные типы исключений, которые можно безопасно игнорировать (в основном,OperationCanceledException
), и ничего не делая с ними. Все преимущества обоих вариантов. - person   schedule 07.09.2012