web-dev-qa-db-fra.com

Comment attendre sur un délégué asynchrone

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?

31
Uriil

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();
49
Yuval Itzchakov

"Async void est réservé aux gestionnaires d'événements de niveau supérieur",

http://channel9.msdn.com/Series/Three-Essential-Tips-for-Async/Tip-1-Async-void-is-for-top-level-event-handlers-only

4
Lex Li

Récemment, j'ai trouvé que NUnit était capable de awaitasync voidtests. 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

2
Uriil