<p>Lorsque vous utilisez <code>async</code> et <code>await</code>, le compilateur génère une machine à états en arrière-plan.</p>
<p>Voici un exemple avec lequel j’espère pouvoir expliquer certains des détails de haut niveau de ce qui se passe :</p>
<pre><code class="lang-auto">public async Task MyMethodAsync()
{
Task<int> longRunningTask = LongRunningOperationAsync();
// independent work which doesn't need the result of LongRunningOperationAsync can be done here
//and now we call await on the task
int result = await longRunningTask;
//use the result
Console.WriteLine(result);
}
public async Task<int> LongRunningOperationAsync() // assume we return an int from this long running operation
{
await Task.Delay(1000); // 1 second delay
return 1;
}
</code></pre>
<p>Bien, alors que se passe-t-il ici :</p>
<ul>
<li></li>
</ul>
<p><code>Task<int> longRunningTask = LongRunningOperationAsync();</code> commence l’exécution de <code>LongRunningOperation</code></p>
<ul>
<li></li>
</ul>
<p>Un travail indépendant est effectué sur, supposons, le thread principal (Thread ID = 1) puis <code>await longRunningTask</code> est atteint.</p>
<p>Maintenant, si <code>longRunningTask</code> n’est pas terminé et est toujours en cours d’exécution, <code>MyMethodAsync()</code> retournera à sa méthode appelante, ainsi le thread principal n’est pas bloqué. Lorsque <code>longRunningTask</code> est terminé, un thread du ThreadPool (qui peut être n’importe quel thread) retournera à <code>MyMethodAsync()</code> dans son contexte précédent et continuera l’exécution (dans ce cas, l’affichage du résultat dans la console).</p>
<p>Un second cas serait que <code>longRunningTask</code> ait déjà terminé son exécution et que le résultat soit disponible. En atteignant <code>await longRunningTask</code>, nous avons déjà le résultat donc le code continuera à s’exécuter sur le même thread. (dans ce cas, l’affichage du résultat dans la console). Bien sûr, ce n’est pas le cas pour l’exemple ci-dessus, où il y a un <code>Task.Delay(1000)</code> impliqué.</p>