168 votes

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 des méthodes async void de feu et d'oublier pour démarrer des tâches, car il n'y a pas de suivi de la tâche en attente et il est délicat de gérer les exceptions qui pourraient être levées à l'intérieur d'une telle méthode.

Devrais-je généralement éviter les gestionnaires d'événements async void, également? Par exemple,

private async void Form_Load(object sender, System.EventArgs e)
{
        await Task.Delay(2000); // faire un travail asynchrone
        // ...
} 

Je peux le réécrire comme ceci:

Tâche onFormLoadTask = null; // suivre la tâche, peut implémenter l'annulation

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); // faire un travail asynchrone
        // ...
} 

Quels sont les risques cachés pour les gestionnaires d'événements asynchrones, à part la possible réentrance?

197voto

Stephen Cleary Points 91731

La directive est d'éviter async void sauf lorsqu'il est utilisé dans un gestionnaire d'événements, donc l'utilisation de async void dans un gestionnaire d'événements est OK.

Cela dit, pour des raisons de tests unitaires, j'aime souvent factoriser la logique de tous les méthodes async void. 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);
}

61voto

Eric Lippert Points 300275

Devrais-je généralement éviter les gestionnaires d'événements async void, aussi?

Généralement, les gestionnaires d'événements sont le seul cas où une méthode async void n'est pas un potentiel code suspect.

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

8voto

Alexander Zwitbaum Points 1627

Si vous utilisez ReSharper, une extension ReCommended gratuite pourrait vous être utile. Elle analyse les méthodes "async void" et met en évidence leur utilisation inappropriée. L'extension peut distinguer les différents usages de async void et fournir les correctifs rapides appropriés décrits ici : wiki de l'extension ReCommended.

7voto

DotNet Dreamer Points 2512

Oui, généralement async void des gestionnaires d'événements est le seul cas. Si vous voulez en savoir plus à ce sujet, vous pouvez consulter une excellente vidéo ici sur la chaîne 9

Le seul cas où ce type de déclenchement et oubli est approprié est dans les gestionnaires d'événements de niveau supérieur. Chaque autre méthode asynchrone dans votre code devrait retourner "async Task".

voici le lien

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X