Disons que j’ai deux méthodes asynchrones
public async static Task RunAsync1() { await Task.Delay(2000); await Task.Delay(2000); }
et
public async static Task RunAsync2() { var t1 = Task.Delay(2000); var t2 = Task.Delay(2000); await t1; await t2; }
Ensuite, je l’utilise comme
public static void M() { RunAsync1().GetAwaiter().GetResult(); RunAsync2().GetAwaiter().GetResult(); }
Dans un résultat, RunAsync1
exécutera 4sec mais RunAsync2
seulement 2sec
Quelqu’un peut-il expliquer pourquoi? Les méthodes sont presque les mêmes. Quelle est la différence?
Dans la seconde méthode, 2 tâches sont démarrées en même temps. Ils finiront tous les deux en 2 secondes (car ils courent en parallèle). Dans la première méthode, vous exécutez une méthode (2 secondes), attendez la fin, puis démarrez la seconde (2 secondes supplémentaires). Le point clé ici est Task.Delay(..)
commence dès que vous l’appelez, pas quand vous l’attendez.
Pour clarifier davantage, première méthode:
var t1 = Task.Delay(2000); // this task is running now await t1; // returns 2 seconds later var t2 = Task.Delay(2000); // this task is running now await t2; // returns 2 more seconds later
Deuxième méthode:
var t1 = Task.Delay(2000); var t2 = Task.Delay(2000); // both are running now await t1; // returns in about 2 seconds await t2; // returns almost immediately, because t2 is already running for 2 seconds
Examinez votre code:
public async static Task RunAsync1() { await Task.Delay(2000); // Start a delay task, and WAIT for it to finish await Task.Delay(2000); // Start a delay task, and WAIT for it to finish }
La seconde await Task.Delay(2000);
est appelé après la fin du premier appel (après 2 secondes).
Alors que la deuxième méthode,
public async static Task RunAsync2() { var t1 = Task.Delay(2000); // Start a task var t2 = Task.Delay(2000); // Start a task await t1; // Wait for task to finish await t2; // Wait for task to finish }
Donc, les tâches t1 et t2 s’exécutent en même temps.
Si vous le changez en
public async static Task RunAsync3() { var t1 = Task.Delay(2000); // Start a task await t1; // Wait for task to finish var t2 = Task.Delay(2000); // Start a task await t2; // Wait for task to finish }
vous obtiendrez les mêmes résultats que dans RunAsync1.
Dans le premier cas, vous dites
public async static Task RunAsync1() { var t1 = Task.Delay(2000); await t1; var t2 = await Task.Delay(2000); await t2; }
Ce qui équivaut à
Le deuxième cas est
public async static Task RunAsync2() { var t1 = Task.Delay(2000); var t2 = Task.Delay(2000); await t1; await t2; }
En d’autres termes, dans le premier cas, vous effectuez une programmation asynchrone séquentielle et le second est une programmation asynchrone parallèle.
Chaque fois que vous démarrez une tâche. Cela a déjà commencé lorsque vous l’avez créé, pas lorsque vous avez appelé await
.
Si vous créez une tâche et la mettez dans une variable, il est possible qu’elle se termine déjà lorsque vous l’attendez. C’est ce qui arrive à votre deuxième cas. await
s’assure juste qu’il doit finir avant de continuer.