web-dev-qa-db-fra.com

Devrais-je éviter les gestionnaires d'événements 'async void'?

Je sais qu’il est généralement considéré comme une mauvaise idée d’utiliser le principe du feu et oublier async void méthodes pour démarrer des tâches, car il n’existe aucune trace de la tâche en attente et il est difficile de gérer les exceptions qui pourraient être émises au sein d’une telle méthode.

Dois-je généralement éviter async void _ gestionnaires d’événements également? Par exemple,

private async void Form_Load(object sender, System.EventArgs e)
{
        await Task.Delay(2000); // do async work
        // ...
} 

Je peux le réécrire comme ceci:

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
        // ...
} 

Quelles sont les roches sous-marines pour les gestionnaires d’événements asynchrones, en plus d’une réentrée possible?

103
avo

La ligne directrice est d'éviter async voidexcepté lorsqu’il est utilisé dans un gestionnaire d’événements, aussi utiliser async void dans un gestionnaire d'événements est OK.

Cela dit, pour tests unitaires des raisons pour lesquelles j’aime souvent décomposer la logique de toutes les async void méthodes. Par exemple.,

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);
}
137
Stephen Cleary

Devrais-je généralement éviter également les gestionnaires d'événements vides asynchrones?

En règle générale, les gestionnaires d'événements sont le seul cas où une méthode asynchrone vide n'est pas une odeur de code potentielle.

Maintenant, si vous avez besoin de suivre la tâche pour une raison quelconque, la technique que vous décrivez est parfaitement raisonnable.

42
Eric Lippert

Oui, en règle générale, le seul cas est le vide asynchrone des gestionnaires d’événements. Si vous voulez en savoir plus à ce sujet, vous pouvez visionner une superbe vidéo ici au canal 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".

voici le lien

5
DotNet Dreamer

Si vous utilisez ReSharper, une version gratuite ReCommended Extension pourrait vous être utile. Il analyse les méthodes de "vide asynchrone" et met en évidence lorsqu'il est utilisé de manière inappropriée. L'extension peut distinguer différentes utilisations de vide asynchrone et fournir les solutions rapides appropriées décrites ici: wiki de ReCommended-Extension .

3
Alexander Zwitbaum