In ASP.NET HttpClient.GetAsync(...)
kommt es bei der Verwendung von await
/async
Bei Verwendung der neuen async
/await
-Sprachfunktionen und der Aufgaben-API in .NET 4.5 kann es manchmal vorkommen, dass die „wartenden“ Ergebnisse von httpClient.GetAsync(...)
hängen bleiben. Dies ist auf einen Missbrauch der API zurückzuführen.
Erklärung
In ASP.NET kann jeweils nur ein Thread eine Anfrage bearbeiten. Bei Bedarf kann eine parallele Verarbeitung durchgeführt werden, es müssen jedoch zusätzliche Threads aus dem Thread-Pool ausgeliehen werden, und diese Threads haben keinen Anforderungskontext. Dies wird vom ASP.NET SynchronizationContext verwaltet.
Standardmäßig werden Methoden beim Warten auf eine Aufgabe im erfassten SynchronizationContext oder im erfassten TaskScheduler fortgesetzt (wenn kein SynchronizationContext vorhanden ist). Normalerweise ist dies ideal: Die asynchrone Controller-Aktion wartet auf etwas, und wenn sie fortgesetzt wird, wird sie mit dem Anforderungskontext fortgesetzt.
Test5Controller.Get
Diese spezielle Controller-Methode führt AsyncAwait_GetSomeDataAsync aus (im Kontext einer ASP.NET-Anfrage). AsyncAwait_GetSomeDataAsync führt HttpClient.GetAsync aus (im Kontext einer ASP.NET-Anfrage). Die HTTP-Anfrage wird gesendet und HttpClient.GetAsync gibt eine nicht abgeschlossene Aufgabe zurück. Dann wartet AsyncAwait_GetSomeDataAsync auf die unvollendete Aufgabe und gibt daher eine unvollendete Aufgabe zurück. Jetzt blockiert Test5Controller.Get den aktuellen Thread, bis die Aufgabe abgeschlossen ist.
Die HTTP-Antwort kommt und die von HttpClient.GetAsync zurückgegebene Aufgabe ist abgeschlossen. AsyncAwait_GetSomeDataAsync versucht dann, im ASP.NET-Anforderungskontext fortzufahren. Allerdings gibt es in diesem Zusammenhang bereits einen Thread: den in Test5Controller.Get blockierten Thread. Dies kann zu einem Deadlock führen.
Best Practices
Um dieses Problem zu beheben, wird Folgendes empfohlen:
ConfigureAwait(false)
in Ihrer „Bibliothek“ nach Möglichkeit asynchrone Methoden. In diesem Fall wird AsyncAwait_GetSomeDataAsync in result = await httpClient.GetAsync("http://stackoverflow.com", HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
await
anstelle von „GetResult“ (Task.Result
, Task.Wait
sollte auch durch await
ersetzt werden). Wenn Sie diese Best Practices befolgen, wird die Fortsetzung (der Rest der AsyncAwait_GetSomeDataAsync-Methode) in einem normalen Thread-Pool-Thread ausgeführt, ohne dass der ASP.NET-Anforderungskontext eingegeben werden muss, und der Controller selbst ist asynchron (blockiert ihn nicht). Anfragethread).
Das obige ist der detaillierte Inhalt vonWarum ist `httpclient.getAsync (...)` manchmal Deadlock bei Verwendung von '` aint '/` async` in ASP.net?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!