web-dev-qa-db-fra.com

async + attendre == synchronisation?

Je suis tombé sur ce post qui parle de faire des requêtes web asynchrones.

Maintenant, la simplicité mise à part, si dans le monde réel, tout ce que vous faites est de faire une demande asynchrone et de l'attendre à la ligne suivante, n'est-ce pas la même chose que de faire un appel de synchronisation en premier lieu?

25
Mrchief

Non, async + await != sync, en raison de continuation

Depuis MSDN 'Programmation asynchrone avec Async et Await (C # et Visual Basic)'

Les méthodes asynchrones sont destinées à être des opérations non bloquantes. Une expression d'attente dans une méthode asynchrone ne bloque pas le thread en cours pendant l'exécution de la tâche attendue. Au lieu de cela, l'expression signe le reste de la méthode en tant que continuation et renvoie le contrôle à l'appelant de la méthode async .

Par exemple, l'exécution asynchrone ne bloquera pas le thread d'interface utilisateur et Some TextBox.Text sera mis à jour une fois le téléchargement terminé

private async void OnButtonClick()
{
   SomeTextBox.Text = await new WebClient().DownloadStringTaskAsync("http://stackoverflow.com/");
}
34
Akim

Non ce n'est pas pareil.

Votre bloc de code async attend que l'appel await revienne pour continuer, mais le reste de votre application n'attend pas et peut continuer comme d'habitude.

En revanche, un appel synchrone ferait attendre votre application entière ou votre thread jusqu'à ce que le code ait fini de s'exécuter pour continuer avec autre chose.

6
Rachel

S'il vous plaît permettez-moi de clarifier les choses en ce qui concerne async/wait.

Lorsque l'attente est rencontrée, la machine d'état sous-jacente permet au contrôle d'être retourné immédiatement. Ensuite, lorsque l'appel attendu est terminé, la machine d'état sous-jacente permet à l'exécution de reprendre sur la ligne après l'appel attendu.

Par conséquent, le bloc asynchrone n'est pas bloqué et n'attend pas la fin de l'appel attendu; Le contrôle est retourné immédiatement lorsque la commande d'attente est rencontrée.

La machine à états sous-jacente fait partie de la "magie" derrière l'utilisation de l'async/wait qui n'est pas désaffectée et manquée.

5
Cedric Harris

Je suis tombé dessus avec la même question à l'esprit, mais après avoir lu les réponses, la question semble persister, confuse par les références à la "magie sous le capot".

De la mention ci-dessus programmation asynchrone :

  • Le mot clé async transforme une méthode en méthode asynchrone, ce qui vous permet d'utiliser le mot clé await dans son corps.
  • Lorsque le mot clé await est appliqué, il suspend la méthode d'appel et rend le contrôle à son appelant jusqu'à la fin de la tâche attendue.
  • await ne peut être utilisé qu'à l'intérieur d'une méthode async.

Le contexte qui rencontre await est-il bloqué?

  • Oui . Il s'agit essentiellement d'une barrière de synchronisation locale pour maintenir un état connu dans le contexte de l'exécution; sauf que d'autres contextes, le cas échéant, ne sont pas joints.

Est-ce que le reste du bloc d'application à await?

  • Cela dépend de la façon dont votre application est écrite. S'il s'agit d'une série de tâches dépendantes awaited lancées séquentiellement dans le même contexte (voir: Essayer de comprendre un comportement asynchrone/attendre )

    await asyncCall1();
    await asyncCall2();  // waits for asyncCall1() to complete
    

    de cette façon, chaque await bloquerait le frai du suivant.

    En revanche, les mêmes tâches dépendantes lancées en parallèle s'exécuteraient en parallèle et le contexte ne se bloquerait qu'au resp. await:

    Task<int> t1 = asyncCall1();
    Task<string> t2 = asyncCall2();  // runs in parallel with asyncCall1()
    int val = await t1;
    string str = await t2;  // waits for asyncCall1() to complete
    

    En général, await renvoie l'exécution au contexte externe, d'où le contexte actuel est appelé. Cependant, si le contexte externe lui-même attend le courant, c'est comme un awaits séquentiel dans le même contexte.

Donc, pour profiter des avantages de async, il faut concevoir l'application pour exécuter plusieurs contextes parallèles (UI, data-client, etc.), puis await dans un contexte donne l'exécution à d'autres contextes, ainsi l'application entière ne bloquerait pas sur un await individuel.

2
oversynched