Dans l'une des vidéos MVA, j'ai vu la construction suivante:
static void Main(string[] args)
{
Action testAction = async () =>
{
Console.WriteLine("In");
await Task.Delay(100);
Console.WriteLine("After first delay");
await Task.Delay(100);
Console.WriteLine("After second delay");
};
testAction.Invoke();
}
Le résultat de l'exécution sera:
In
Press any key to continue . . .
Il se compile parfaitement, mais pour l'instant je ne vois aucun moyen de l'attendre. Je pourrais mettre Thread.Sleep
ou Console.ReadKey
après l'invocation, mais ce n'est pas ce que je veux.
Alors, comment ce délégué devrait-il être modifié pour devenir attendu? (Ou au moins comment puis-je suivre cette exécution terminée?)
Y a-t-il une utilisation pratique de ces délégués?
Pour que quelque chose soit attendu, il doit être attendable. Comme void
ne l'est pas, vous ne pouvez attendre aucun délégué Action
.
Un attendable est tout type qui implémente une méthode GetAwaiter
, qui renvoie un type qui implémente INotifyCompletion
ou ICriticalNotifyCompletion
, comme Task
et Task<T>
, par exemple.
Si vous voulez attendre un délégué, utilisez Func<Task>
, qui est l'équivalent d'une méthode nommée avec la signature suivante:
public Task Func()
Donc, pour attendre, changez votre méthode en:
static void Main(string[] args)
{
Func<Task> testFunc = async () =>
{
Console.WriteLine("In");
await Task.Delay(100);
Console.WriteLine("First delay");
await Task.Delay(100);
Console.WriteLine("Second delay");
};
}
Et maintenant vous pouvez l'attendre:
await testFunc();
"Async void est réservé aux gestionnaires d'événements de niveau supérieur",
Récemment, j'ai trouvé que NUnit était capable de await
async void
tests. Voici une bonne description de son fonctionnement: Comment nunit attend-elle avec succès que les méthodes async void se terminent?
Vous ne l'utiliserez pas dans les tâches régulières, mais il est bon de savoir que c'est possible