По каким сценариям можно использовать
public async Task AsyncMethod(int num)
вместо
public async void AsyncMethod(int num)
Единственный сценарий, который я могу придумать, - это если вам нужна задача, чтобы отслеживать ее прогресс.
Кроме того, в следующем методе ненужны ли ключевые слова async и await?
public static async void AsyncMethod2(int num)
{
await Task.Factory.StartNew(() => Thread.Sleep(num));
}
c#
asynchronous
.net-4.5
user981225
источник
источник
Foo()
стал быFooAsync()
.Thread.Sleep
с вашими задачами, вы должныawait Task.Delay(num)
вместо этогоTask.Delay
не в этом, такTask.AsyncDelay
как все методы в задании являются асинхроннымиasync void
вместо этогоasync Task
. Сбой метода из-за того, что он использовал объект контекста Entity Framework, объявленный как член контроллера, был удален до завершения выполнения метода. Фреймворк располагал контроллер до завершения его метода. Я изменил метод асинхронной задачи, и это сработало.Ответы:
1) Обычно вы хотите вернуть
Task
. Основное исключение должно быть, когда вам нужно иметьvoid
тип возвращаемого значения (для событий). Если нет никаких причин, чтобы запретить вызывающему абоненту выполнятьawait
вашу задачу, зачем это запрещать?2)
async
методы, которые возвращают,void
являются специальными в другом аспекте: они представляют асинхронные операции верхнего уровня и имеют дополнительные правила, которые вступают в действие, когда ваша задача возвращает исключение. Проще всего показать разницу с помощью примера:f
исключение всегда "соблюдается". Исключение, которое оставляет асинхронный метод верхнего уровня, просто обрабатывается как любое другое необработанное исключение.g
исключение никогда не наблюдается. Когда сборщик мусора приходит для очистки задачи, он видит, что задача вызвала исключение, и никто не обработал исключение. Когда это происходит,TaskScheduler.UnobservedTaskException
обработчик запускается. Никогда не позволяй этому случиться. Чтобы использовать ваш пример,Да, использовать
async
иawait
здесь, они гарантируют, что ваш метод все еще работает правильно, если выброшено исключение.Для получения дополнительной информации см .: http://msdn.microsoft.com/en-us/magazine/jj991977.aspx
источник
f
а неg
в своем комментарии. Исключение изf
передается вSynchronizationContext
.g
подниметUnobservedTaskException
, ноUTE
больше не завершит процесс, если он не обработан. В некоторых ситуациях допустимо иметь такие «асинхронные исключения», которые игнорируются.WhenAny
несколькоTask
s, что приводит к исключениям. Вам часто приходится иметь дело только с первым, и вы часто хотите игнорировать других.WhenAny
в первую очередь, можно ли игнорировать другие исключения: основной сценарий использования, который у меня есть, все равно заканчивается ожиданием оставшихся задач, когда завершается любая с или без исключения.Я сталкивалась с этим очень полезно статей о
async
иvoid
написала Жером Лавану: https://jaylee.org/archive/2012/07/08/c-sharp-async-tips-and-tricks-part-2-async-void .htmlСуть в том, что это
async+void
может привести к сбою системы и обычно должно использоваться только в обработчиках событий на стороне пользовательского интерфейса.источник
Я получил четкое представление из этого заявления.
Исключения из асинхронного метода Void нельзя обнаружить с помощью Catch
Эти исключения можно наблюдать с помощью AppDomain.UnhandledException или аналогичного события перехвата для приложений GUI / ASP.NET, но использование этих событий для регулярной обработки исключений является рецептом для невозможности обслуживания (он приводит к сбою приложения).
Асинхронные методы void имеют различную семантику создания. Асинхронные методы, возвращающие Task или Task, могут быть легко составлены с использованием await, Task.WhenAny, Task.WhenAll и так далее. Асинхронные методы, возвращающие void, не обеспечивают простой способ уведомить вызывающий код о том, что они завершили. Легко запустить несколько асинхронных пустых методов, но нелегко определить, когда они закончили. Асинхронные методы void будут уведомлять свой SynchronizationContext при запуске и завершении, но пользовательский SynchronizationContext является сложным решением для обычного кода приложения.
Метод Async Void полезен при использовании синхронного обработчика событий, потому что они вызывают свои исключения непосредственно в SynchronizationContext, что аналогично тому, как ведут себя синхронные обработчики событий.
Для получения более подробной информации перейдите по этой ссылке https://msdn.microsoft.com/en-us/magazine/jj991977.aspx
источник
Проблема с вызовом async void заключается в том, что вы даже не получаете задачу обратно, у вас нет возможности узнать, когда задача функции была выполнена (см. Https://blogs.msdn.microsoft.com/oldnewthing/20170720-00/ ? p = 96655 )
Вот три способа вызова асинхронной функции:
источник
Я думаю, что вы также можете использовать
async void
для запуска фоновых операций, если вы будете осторожны, чтобы ловить исключения. Мысли?источник
Мой ответ прост, вы не можете ждать пустого метода
Поэтому, если метод асинхронный, лучше быть ожидаемым, потому что вы можете потерять преимущество асинхронности.
источник
Согласно документации Microsoft , НИКОГДА не следует использовать
async void
источник