C # Async et Wait Not Work

Pourquoi le async suivant async et await ne fonctionne-t-il pas? J’essaie d’apprendre que cela voudrait comprendre ce qui ne va pas avec mon code.

 class Program { static void Main(ssortingng[] args) { callCount(); } static void count() { for (int i = 0; i < 5; i++) { System.Threading.Thread.Sleep(2000); Console.WriteLine("count loop: " + i); } } static async void callCount() { Task task = new Task(count); task.Start(); for (int i = 0; i < 3; i++) { System.Threading.Thread.Sleep(4000); Console.WriteLine("Writing from callCount loop: " + i); } Console.WriteLine("just before await"); await task; Console.WriteLine("callCount completed"); } } 

Le programme va démarrer la méthode count () mais abandonne sans la terminer. Avec la tâche d’attente; Je m’attendais à ce que l’instruction attende de terminer toutes les boucles de la méthode count () (0, 1, 2, 3, 4) avant de quitter. Je ne reçois que “compte boucle: 0”. Mais cela passe par tout callCount (). C’est comme attendre que la tâche ne fasse rien. Je veux que count () et callCount () s’exécutent de manière asynchrone et reviennent en mode principal une fois l’opération terminée.

Lorsque vous exécutez une méthode async , elle s’exécute de manière synchrone jusqu’à atteindre une instruction await , puis le rest du code s’exécute de manière asynchrone, puis retourne à l’appelant.

Dans votre code callCount() commence à s’exécuter de manière synchrone pour await task , puis retour à Main() méthode Main() . Et comme vous n’attendez pas que la méthode soit terminée, le programme se termine sans méthode count() peut s’achever.

Vous pouvez voir le comportement souhaité en remplaçant le type de retour par Task et en appelant Wait() dans Main() méthode Main() .

 static void Main(ssortingng[] args) { callCount().Wait(); } static void count() { for (int i = 0; i < 5; i++) { System.Threading.Thread.Sleep(2000); Console.WriteLine("count loop: " + i); } } static async Task callCount() { Task task = new Task(count); task.Start(); for (int i = 0; i < 3; i++) { System.Threading.Thread.Sleep(1000); Console.WriteLine("Writing from callCount loop: " + i); } Console.WriteLine("just before await"); await task; Console.WriteLine("callCount completed"); } 

EDIT: Voici comment votre code s'exécute:

(pour une meilleure compréhension, permet aux changements de CallCount() retourner le type à Task )

  1. le programme commence par Main() méthode Main() .
  2. CallCount() est appelée.
  3. la tâche est créée, tout cela dans le même fil.
  4. Ensuite, la tâche est lancée. À ce stade, un nouveau thread est créé en exécutant la méthode Count() en parallèle.
  5. L'exécution continue dans CallCount (), car la boucle est exécutée et "juste avant wait" est imprimé.
  6. Alors await task; est atteint. C’est à ce moment que le motif attente asynchrone joue son rôle. Wait() n’est pas comme Wait() , il ne bloque pas le thread actuel tant que la tâche n’est pas terminée, mais renvoie le contrôle d’exécution à la méthode Main() et à toutes les instructions restantes de CallCount() (dans ce cas, Console.WriteLine("callCount completed"); ) sera exécuté une fois la tâche terminée.
  7. Dans Main() , l'appel de CallCount() renvoie une Task (avec les instructions restantes de CallCount() et la tâche d'origine) et l'exécution se poursuit.
  8. Si vous n'attendez pas que cette tâche se termine, l'exécution dans Main() continuera à finaliser le programme et les tâches en cours de destruction.
  9. Si vous appelez Wait() (si CallCount() est vide, vous n'avez pas de tâche à attendre), vous laissez la tâche se terminer, en maintenant Main() pour l'exécution Count() et "callCount completed" en cours d'impression.

Si vous souhaitez attendre que la tâche du compte se termine dans CallCount() sans retourner à Main() méthode Main() , appelez task.Wait(); , tout le programme attendra Count() , mais ce n’est pas ce que wait fera.

Ce lien explique en détail le modèle d’attente asynchrone.

J'espère que ce diagramme de stream de travail de votre code vous aide.

entrez la description de l'image ici