web-dev-qa-db-fra.com

Async / Await utilise-t-il Task.Run pour démarrer un nouveau thread de manière asynchrone?

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?

33
syncis
  1. La création de méthodes Async a pour but de les attendre plus tard. Un peu comme "Je vais mettre cette eau à ébullition, finir de préparer le reste de mes ingrédients pour la soupe, puis revenir dans la casserole et attendre que l'eau ait fini de bouillir pour que je puisse faire le dîner." Vous démarrez l'eau bouillante, ce qu'elle fait de manière asynchrone pendant que vous faites d'autres choses, mais vous devez finalement vous arrêter et l'attendre. Si vous voulez "tirer et oublier", alors Async et Await ne sont pas nécessaires.

Méthode la plus simple pour faire un feu et oublier la méthode en C #?

  1. Le démarrage d'une nouvelle tâche met cette tâche en attente d'exécution sur un thread de pool de threads. Les threads s'exécutent dans le contexte du processus (par exemple l'exécutable qui exécute votre application). S'il s'agit d'une application Web exécutée sous IIS, ce thread est créé dans le contexte du processus de travail IIS. Ce thread s'exécute séparément du thread d'exécution principal, donc il s'éteint et fait sa quelle que soit la fonction de votre thread d'exécution principal, et en même temps, votre thread d'exécution principal poursuit son propre travail.
18
DVK

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.

10

1

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 DoSomethingTask n'est pas terminé.

  • Cas vous await il : DoSomething est appelé et la phrase suivante est exécutée une fois DoSomethingTask 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 .

2

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.

Questions et réponses intéressantes

Vous voudrez peut-être revoir ces autres questions et réponses:

OP a dit ...

[...] 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);
}
9
Matías Fidemraizer