Maison > développement back-end > C++ > Pourquoi `httpclient.getasync (...)` est-il parfois imprégné lorsque vous utilisez `Await` /` async` dans asp.net?

Pourquoi `httpclient.getasync (...)` est-il parfois imprégné lorsque vous utilisez `Await` /` async` dans asp.net?

Mary-Kate Olsen
Libérer: 2025-01-25 13:37:09
original
549 Les gens l'ont consulté

Why does `HttpClient.GetAsync(...)` sometimes deadlock when using `await`/`async` in ASP.NET?

Dans ASP.NET HttpClient.GetAsync(...) des blocages occasionnels se produisent lors de l'utilisation de await/async

Lors de l'utilisation des nouvelles fonctionnalités du langage async/await et de l'API Tasks dans .NET 4.5, les résultats « en attente » de httpClient.GetAsync(...) peuvent parfois rester bloqués. Cela est dû à une mauvaise utilisation de l'API.

Explication

Dans ASP.NET, un seul thread peut gérer une requête à la fois. Un traitement parallèle peut être effectué si vous le souhaitez, mais des threads supplémentaires devront être empruntés au pool de threads et ces threads n'auront aucun contexte de requête. Ceci est géré par ASP.NET SynchronizationContext.

Par défaut, lors de l'attente d'une tâche, les méthodes reprennent sur le SynchronizationContext capturé ou le TaskScheduler capturé (s'il n'y a pas de SynchronizationContext). Normalement, c'est l'idéal : l'action du contrôleur asynchrone attendra quelque chose, et lorsqu'elle reprendra, elle reprendra en utilisant le contexte de requête.

Test5Controller.Get

Cette méthode de contrôleur particulière exécute AsyncAwait_GetSomeDataAsync (dans le contexte d'une requête ASP.NET). AsyncAwait_GetSomeDataAsync exécute HttpClient.GetAsync (dans le contexte d'une requête ASP.NET). La requête HTTP est envoyée et HttpClient.GetAsync renvoie une tâche inachevée. Ensuite, AsyncAwait_GetSomeDataAsync attend la tâche inachevée et renvoie donc une tâche inachevée. Désormais, Test5Controller.Get bloque le thread actuel jusqu'à la fin de la tâche.

La réponse HTTP arrive et la tâche renvoyée par HttpClient.GetAsync est terminée. AsyncAwait_GetSomeDataAsync tente ensuite de reprendre dans le contexte de requête ASP.NET. Cependant, il existe déjà un thread dans ce contexte : le thread bloqué dans Test5Controller.Get. Cela peut conduire à une impasse.

Bonnes pratiques

Pour corriger ce problème, il est recommandé :

  • Utilisez ConfigureAwait(false) dans les méthodes asynchrones de votre "bibliothèque" autant que possible. Dans ce cas, AsyncAwait_GetSomeDataAsync sera remplacé par result = await httpClient.GetAsync("http://stackoverflow.com", HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
  • Évitez de bloquer les tâches ; utilisez await au lieu de "GetResult" (Task.Result, Task.Wait doit également être remplacé par await).

En suivant ces bonnes pratiques, la suite (le reste de la méthode AsyncAwait_GetSomeDataAsync) s'exécutera sur un thread de pool de threads normal sans avoir besoin d'entrer dans le contexte de requête ASP.NET, et le contrôleur lui-même est asynchrone (ne bloquera pas le fil de demande) .

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal