0
votes

"Tâche Async" vs "Tâche de retour.Run"

Je suis nouveau pour async / attendre le modèle C # et essayer de comprendre si ces deux options sont essentiellement la même chose: xxx

et cette xxx

Je pense que la 1ère reprise utilisera un fil supplémentaire de la piscine ... et cela enveloppe également une tâche supplémentaire. Ou je me trompe?


3 Réponses :


7
votes

Tâche.Run Faire la queue son délégué à la piscine de thread. Cela provoque deux choses importantes:

  1. n'importe quel code dans dostuff avant le premier attendre exécuter sur un thread de piscine de thread, au lieu de sur le thread d'appel .
  2. Le code dans dostuff sera exécuté dans un contexte de piscine de thread, au lieu de Utilisation du contexte actuel du fil d'appel .

    la plupart de l'époque, faire des travaux asynchrones dans Task.Run est une erreur. Mais il est parfois utile, disons si dostuff est un travail de calcul lourd avant qu'il agit de manière asynchrone, alors tâche.run pourrait être utilisé pour déplacer ce travail d'un fil d'interface utilisateur.


0 commentaires

1
votes

Le nom de la méthode transmet la raison pour laquelle il est fait comme ça, "longroin". Vous pouvez passer un drapeau de création longRunning à Tâche.run () (que cet échantillon ne fonctionne pas) et en tant que fil de mise en oeuvre pure, l'exécution allouera un fil séparé pour cela .

Même votre deuxième exemple n'est pas complètement correct, en fonction des circonstances. S'il s'agit d'une bibliothèque, alors il devrait vraiment être attendre dostuff (). ConfigureaWait (Faux); .


0 commentaires


2
votes

Ils sont très similaires em>, mais il y a une chance que dostuff code> puisse compléter de manière synchrone; Si cela se produit, votre deuxième ( attendre code> uniquement) bloquerait la longueur de longue durée qui prend ce qui prend, où, à mesure que la première ( tâche.run.run code>) retournerait toujours incomplète à l'appelant (déroulant leur pile et la planification d'une continuation), et faire fonctionner le travail de blocage sur le fil de la piscine.

Les deux options peuvent être souhaitables, dans différents scénarios! P>

Cependant, il existe une troisième option, qui exprime exactement em> l'intention de "exécuter le reste ailleurs" aussi longtemps que strong> vous n'avez pas de synccontext code>: p>

public async Task LongRunningMethod()
{
    await Task.Yield();
    await DoStuff(); // possibly with .ConfigureAwait(false)
}


6 commentaires

Vous devriez appeler vous-même le dieu de system.threading.tasks.task .


@Tanveerbadar céder avant moi!


Si LongRunningMethod est appelé sur le fil de l'interface graphique, Dostuff fonctionnera également sur le fil de l'interface graphique, pas dans la piscine de fil. Vous aurez besoin d'un configureawait pour l'obtenir dans la piscine.


@San oui, vous avez raison - s'il y a un contexte de synchronisation, cela ira retour dans le contexte de synchronisation; Je vais réfléchir à cela (je suis tellement habitué à vivre dans un monde sans synchronisation-contexte; je ne les manques pas!)


Pourquoi préférer attendre la tâche.yield sur attendre la tâche.run (async () => ? Est-ce plus efficace? Ou juste parce que c'est plus expressif (en supposant que c'est)


@Theodorzoulias surtout sur l'expression de l'intention, même si je crois que cela se rase quelques morceaux - mais pas assez pour la matière dans des scénarios réalistes (si vous utilisez rendez-vous autant, vous ne suffisez probablement pas assez lot )