Les impasses asynchrones dans C #: un problème de contexte de synchronisation
c # 's async
/ await
simplifie la programmation asynchrone, mais une mauvaise manipulation des contextes de synchronisation peut entraîner des blocs de blocage. Les contextes de synchronisation garantissent que le code s'exécute sur le thread correct, mais des problèmes surviennent avec des contextes non réentrants ou monomoder comme le thread d'interface utilisateur ou le contexte de la demande ASP.NET.
Considérez ce scénario:
<code class="language-csharp">public ActionResult ActionAsync() { var data = GetDataAsync().Result; // Blocking call! return View(data); } private async Task<string> GetDataAsync() { var result = await MyWebService.GetDataAsync(); return result.ToString(); }</code>
Ici, ActionAsync
bloque en attendant GetDataAsync
. GetDataAsync
lui-même attend une tâche d'arrière-plan. Cela crée une impasse: le thread principal (dans ActionAsync
) est bloqué, empêchant la tâche d'arrière-plan de terminer, ce qui empêche à son tour GetDataAsync
de terminer, résultant en une impasse perpétuelle.
L'impasse se produit parce que le contexte de synchronisation du thread principal est capturé pendant le await
dans GetDataAsync
, ce qui le rend dépendant de l'achèvement du thread principal. Étant donné que le thread principal est bloqué, cette dépendance empêche GetDataAsync
de terminer.
La solution pour les contextes à thread unique est d'éviter de bloquer les opérations dans les méthodes async
. Utilisez des techniques non bloquantes comme le sondage ou les rappels pour la synchronisation. Au lieu de .Result
, utilisez await
dans ActionAsync
pour résoudre cet exemple spécifique.
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!