Должен ли я избегать обработчиков событий async void?
Я знаю, что, как правило, плохая идея использовать методы fire-and-забыть 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
// ...
}
Каковы подводные камни для асинхронных обработчиков событий, помимо возможного повторного входа?
Ответы
Ответ 1
Рекомендация состоит в том, чтобы избежать async void
, кроме случаев, когда используется в обработчике событий, поэтому использование async void
в обработчике событий в порядке.
Тем не менее, по соображениям модульного тестирования мне часто нравится классифицировать логику всех методов async void
. Например.
public async Task OnFormLoadAsync(object sender, EventArgs e)
{
await Task.Delay(2000);
...
}
private async void Form_Load(object sender, EventArgs e)
{
await OnFormLoadAsync(sender, e);
}
Ответ 2
Должен ли я вообще избегать обработчиков событий async void?
В общем случае обработчики событий - это тот случай, когда метод aoid void не является потенциальным запахом кода.
Теперь, если вам почему-то нужно отследить задание, то техника, которую вы описываете, вполне разумна.
Ответ 3
Да, обычно async void обработчиков событий - единственный случай. Если вы хотите узнать больше об этом, вы можете посмотреть отличное видео здесь, на канале 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".
вот ссылка
Ответ 4
Если вы используете ReSharper, вам может быть полезно бесплатное ReCommended Extension. Он анализирует методы "асинхронные пустоты" и выделяет их при неправильном использовании.
Расширение может различать различные применения async void и предоставлять описанные здесь быстрые исправления: ReCommended-Extension wiki.