J'ai lu beaucoup d'articles et je n'arrive toujours pas à comprendre cette partie.
Considérez ce code:
private async void button1_Click(object sender, EventArgs e)
{
await Dosomething();
}
private async Task<string> Dosomething()
{
await Task.Run((() => "Do Work"));
return "I am done";
}
Première question:
Lorsque je clique sur le bouton, il appellera DoSomething et attendra une tâche qui crée un thread à partir du pool de threads en appelant Task.Run (si je ne me trompe pas) et tout cela s'exécute de manière asynchrone. J'ai donc réussi à créer un fil qui fait mon travail mais le fait de manière asynchrone? Mais considérez que je n'ai pas besoin de résultat en retour, je veux juste que le travail soit fait sans obtenir de résultat, est-il vraiment nécessaire d'utiliser async/wait, et si oui, comment?
Deuxième question:
Lorsque vous exécutez un thread de manière asynchrone, comment cela fonctionne-t-il? Exécute-t-il sur l'interface utilisateur principale mais sur un thread séparé ou s'exécute-t-il sur un thread séparé et distinct est asynchrone à l'intérieur de cette méthode?
Méthode la plus simple pour faire un feu et oublier la méthode en C #?
Le type Task<TResult>
vous oblige à renvoyer un TResult
de votre tâche. Si vous n'avez rien à retourner, vous pouvez utiliser Task
à la place (qui, soit dit en passant, est la classe de base de Task<TResult>
).
Mais gardez à l'esprit qu'une tâche n'est pas un fil conducteur. ne tâche est un travail à effectuer, tandis qu'un thread est un travailleur. À mesure que votre programme s'exécute, les travaux et les travailleurs deviennent disponibles et indisponibles. Dans les coulisses, la bibliothèque affectera vos travaux aux travailleurs disponibles et, comme la création de nouveaux travailleurs est une opération coûteuse, elle préférera généralement réutiliser les travaux existants, via un pool de threads.
Il y a une grande différence si vous n'avez pas await
le Task
ou vous await
:
Cas vous n'avez pas await
il : DoSomething
est appelé mais la phrase suivante est exécutée tandis que DoSomething
Task
n'est pas terminé.
Cas vous await
il : DoSomething
est appelé et la phrase suivante est exécutée une fois DoSomething
Task
est terminé.
Donc, le besoin de async
/await
dépendra de la façon dont vous voulez appeler DoSomething
: si vous ne le faites pas await
, c'est comme l'appeler le tirez et oubliez le chemin .
Exécute-t-il sur l'interface utilisateur principale mais sur un thread séparé ou s'exécute-t-il sur un thread séparé et séparé est asynchrone à l'intérieur de cette méthode?
Le code asynchrone signifie parfois un autre thread (voir ce Q&A Asynchronous vs Multithreading - Y a-t-il une différence? ). Autrement dit, si le code est exécuté dans un thread distinct de celui de l'interface utilisateur ou s'il permet de continuer le traitement du thread d'interface utilisateur pendant sa reprise, c'est bien car la boucle d'interface utilisateur peut toujours mettre à jour l'écran pendant que d'autres tâches sont effectuées dans parallèle sans geler l'interface utilisateur.
Une méthode asynchrone (c'est-à-dire la méthode async
) est un sucre syntaxique pour indiquer au compilateur que les instructions await
doivent être traitées comme une machine d'état. Le compilateur C # transforme votre code async
/await
en une machine d'état où le code en attente d'un résultat Task
est exécuté après le code attendu.
Vous voudrez peut-être revoir ces autres questions et réponses:
[...] Mais cela signifie-t-il que "async/wait" déclenchera un thread et Task.Run déclenchera également un thread ou sont-ils tous les deux le même thread?
L'utilisation de async
- await
ne signifie pas "Je crée un fil" . C'est juste un sucre syntaxique pour implémenter les suites de manière élégante. Une tâche peut ou non être un thread. Par exemple, Task.FromResult(true)
crée une fausse tâche pour pouvoir implémenter une méthode asynchrone sans qu'il soit nécessaire de créer un thread:
public Task<bool> SomeAsync()
{
// This way, this method either decides if its code is asynchronous or
// synchronous, but the caller can await it anyway!
return Task.FromResult(true);
}