Я знаю, что обычно считается плохой идеей использовать async void
методы «запустил и забыл» для запуска задач, потому что не отслеживается ожидающая задача и сложно обрабатывать исключения, которые могут возникнуть внутри такого метода.
Следует ли мне вообще избегать async void
обработчиков событий? Например,
private async void Form_Load(object sender, System.EventArgs e)
{
await Task.Delay(2000); // do async work
// ...
}
Я могу переписать это так:
Task onFormLoadTask = null; // track the task, can implement cancellation
private void Form_Load(object sender, System.EventArgs e)
{
this.onFormLoadTask = OnFormLoadTaskAsync(sender, e);
}
private async Task OnFormLoadTaskAsync(object sender, System.EventArgs e)
{
await Task.Delay(2000); // do async work
// ...
}
Каковы подводные камни для обработчиков асинхронных событий, помимо возможного повторного входа?
Ответы:
Рекомендуется избегать,
async void
за исключением случаев использования в обработчике событий, поэтому использованиеasync void
в обработчике событий - это нормально.Тем не менее, по причинам модульного тестирования мне часто нравится исключать логику всех
async void
методов. Например,источник
Form_Load
доступ кpublic
? Похоже, так код был бы менее подробным.OnFormLoadAsync
. Теперь я понимаю, что это удобный трюк. Спасибо.Handled
Флаг должен быть установлен синхронно; его невозможно использоватьasync
для принятия решения о том, обработано событие или нет.ICommand.Execute
методasync void
; Я считаю это приемлемым , посколькуICommand.Execute
является логически обработчик события.Как правило, обработчики событий - это единственный случай, когда метод void async не является потенциальным запахом кода.
Теперь, если вам по какой-то причине нужно отслеживать задачу, то описанная вами методика вполне разумна.
источник
Да, обычно async без обработчиков событий - единственный случай. Если вы хотите узнать об этом больше, вы можете посмотреть отличное видео здесь, на канале 9.
The only case where this kind of fire-and-forget is appropriate is in top-level event-handlers. Every other async method in your code should return "async Task".
вот ссылка
источник
Если вы используете ReSharper, вам может быть полезно бесплатное расширение ReCommended . Он анализирует методы "async void" и выделяет при неправильном использовании. Расширение может различать различные варианты использования async void и предоставлять соответствующие быстрые исправления, описанные здесь: ReCommended-Extension wiki .
источник