Je sais qu'il est généralement considéré comme une mauvaise idée d'utiliser des méthodes d'incendie et d'oubli async void
pour démarrer des tâches, car il n'y a pas de trace de la tâche en attente et il est difficile de gérer les exceptions qui pourraient être lancées dans une telle méthode.
Dois-je généralement éviter les async void
gestionnaires d'événements? 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 éventuelle ré-entrée?
c#
.net
events
asynchronous
async-await
éviter
la source
la source
Réponses:
La règle est d'éviter
async void
sauf lorsqu'il est utilisé dans un gestionnaire d'événements, donc l'utilisationasync void
dans un gestionnaire d'événements est OK.Cela dit, pour des raisons de tests unitaires , j'aime souvent exclure la logique de toutes les
async void
méthodes. Par exemple,la source
Form_Load
l'accès àpublic
? Il semble que le code serait moins détaillé de cette façon.OnFormLoadAsync
. Je vois maintenant que cela constitue un truc pratique. Merci.Handled
drapeau doit être défini de manière synchrone; il n'est pas possible d'utiliserasync
pour décider si l'événement est géré ou non.ICommand.Execute
méthodeasync void
; Je considère cela comme acceptable car ilICommand.Execute
s'agit logiquement d' un gestionnaire d'événements.En général, les gestionnaires d'événements sont le seul cas où une méthode async void 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.
la source
Oui, généralement asynchrone vide de gestionnaires d'événements est le seul cas. Si vous voulez en savoir plus à ce sujet, vous pouvez regarder une superbe vidéo ici sur le 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
la source
Si vous utilisez ReSharper, une extension ReCommended gratuite pourrait vous être utile. Il analyse les méthodes «async void» et met en évidence lorsqu'elles sont utilisées de manière inappropriée. L'extension peut distinguer différentes utilisations de async void et fournir des correctifs rapides appropriés décrits ici: wiki ReCommended-Extension .
la source