D'après ce que j'ai compris, l'une des principales fonctions de [async
et await
] (https://docs.microsoft.com/en-us/dotnet/csharp/async) est de rendre le code facile à écrire et à lire - mais les utiliser revient-il à créer des threads en arrière-plan pour exécuter une logique de longue durée ?
Je suis en train d'essayer l'exemple le plus basique. J'ai ajouté quelques commentaires en ligne. Pouvez-vous m'éclairer ?
// I don't understand why this method must be marked as `async`.
private async void button1_Click(object sender, EventArgs e)
{
Task<int> access = DoSomethingAsync();
// task independent stuff here
// this line is reached after the 5 seconds sleep from
// DoSomethingAsync() method. Shouldn't it be reached immediately?
int a = 1;
// from my understanding the waiting should be done here.
int x = await access;
}
async Task<int> DoSomethingAsync()
{
// is this executed on a background thread?
System.Threading.Thread.Sleep(5000);
return 1;
}
Suite aux autres réponses, consultez [await (C# Reference)][1].
et plus particulièrement à l'exemple inclus, il explique un peu votre situation.
L'exemple suivant de Windows Forms illustre l'utilisation de await dans une méthode > asynchrone, WaitAsynchronouslyAsyn.
méthode asynchrone, WaitAsynchronouslyAsync. Comparez le comportement de cette méthode méthode avec le comportement de WaitSynchronously. Sans un opérateur await Sans opérateur await appliqué à une tâche, WaitSynchronously s'exécute de manière synchrone. malgré l'utilisation du modificateur async dans sa définition et un appel à Thread.Sleep dans son corps. Thread.Sleep dans son corps.
private async void button1_Click(object sender, EventArgs e)
{
// Call the method that runs asynchronously.
string result = await WaitAsynchronouslyAsync();
// Call the method that runs synchronously.
//string result = await WaitSynchronously ();
// Display the result.
textBox1.Text += result;
}
// The following method runs asynchronously. The UI thread is not
// blocked during the delay. You can move or resize the Form1 window
// while Task.Delay is running.
public async Task<string> WaitAsynchronouslyAsync()
{
await Task.Delay(10000);
return "Finished";
}
// The following method runs synchronously, despite the use of async.
// You cannot move or resize the Form1 window while Thread.Sleep
// is running because the UI thread is blocked.
public async Task<string> WaitSynchronously()
{
// Add a using directive for System.Threading.
Thread.Sleep(10000);
return "Finished";
}
[1] : https://docs.microsoft.com/en-us/dotnet/articles/csharp/language-reference/keywords/await
Je pense que vous avez choisi un mauvais exemple avec System.Threading.Thread.Sleep
.
Le but d'une tâche async
est de la laisser s'exécuter en arrière-plan sans verrouiller le thread principal, par exemple en faisant un DownloadFileAsync
.
System.Threading.Thread.Sleep
n'est pas quelque chose qui est "en train de se faire", il ne fait que dormir, et donc votre prochaine ligne est atteinte après 5 secondes ...
Lisez cet article, je pense que c'est une excellente explication du concept async
et await
: http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx
Pour être honnête, je pense toujours que la meilleure explication est celle qui concerne l'avenir et les promesses sur le site Wikipedia : http://en.wikipedia.org/wiki/Futures_and_promises.
L'idée de base est que vous avez un pool séparé de threads qui exécutent des tâches de manière asynchrone. Lorsque vous l'utilisez. L'objet fait cependant la promesse qu'il exécutera l'opération à un moment donné et vous donnera le résultat lorsque vous le demanderez. Cela signifie qu'il se bloque lorsque vous demandez le résultat et qu'il n'a pas terminé, mais qu'il s'exécute dans le pool de threads sinon.
À partir de là, vous pouvez optimiser les choses : certaines opérations peuvent être implémentées de manière asynchrone et vous pouvez optimiser des choses comme l'entrée/sortie de fichiers et la communication réseau en regroupant les demandes ultérieures et/ou en les réordonnant. Je ne sais pas si cela fait déjà partie de la structure des tâches de Microsoft, mais si ce n'est pas le cas, ce serait l'une des premières choses que j'ajouterais.
En fait, il est possible d'implémenter le modèle futur en quelque sorte avec des rendements en C# 4.0. Si vous voulez savoir comment cela fonctionne exactement, je peux vous recommander ce lien qui fait un travail décent : http://code.google.com/p/fracture/source/browse/trunk/Squared/TaskLib/ . Cependant, si vous commencez à jouer avec vous-même, vous remarquerez que vous avez vraiment besoin d'un support linguistique si vous voulez faire toutes les choses cool - ce qui est exactement ce que Microsoft a fait.