Ich habe einen Anruf aus einer xaml-basierten C#
Metro-Anwendung auf dem Win8 CP. Dieser Aufruf trifft einfach einen Webdienst und gibt JSON-Daten zurück.
HttpMessageHandler handler = new HttpClientHandler();
HttpClient httpClient = new HttpClient(handler);
httpClient.BaseAddress = new Uri("http://192.168.1.101/api/");
var result = await httpClient.GetStreamAsync("weeklyplan");
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(WeeklyPlanData[]));
return (WeeklyPlanData[])ser.ReadObject(result);
Es hängt an der, await
aber der http- Aufruf kehrt tatsächlich fast sofort zurück (bestätigt durch Fiddler); Es ist, als ob das await
ignoriert wird und es einfach dort hängt.
Bevor Sie fragen - JA - ist die Funktion "Privates Netzwerk" aktiviert.
Irgendwelche Ideen, warum das hängen würde?
c#
asynchronous
async-await
dotnet-httpclient
keithwarren7
quelle
quelle
async
Methode? Wirft es keine Ausnahme?Antworten:
Schauen Sie sich diese Antwort auf meine Frage an, die sehr ähnlich zu sein scheint.
Versuchen Sie Folgendes: Rufen Sie
ConfigureAwait(false)
die von zurückgegebene Aufgabe aufGetStreamAsync()
. Z.BOb dies nützlich ist oder nicht, hängt davon ab, wie Ihr obiger Code aufgerufen wird. In meinem Fall hat das Aufrufen der
async
Methode mithilfe dazu geführt,Task.GetAwaiter().GetResult()
dass der Code hängen geblieben ist.Dies liegt daran
GetResult()
, dass der aktuelle Thread blockiert wird, bis die Aufgabe abgeschlossen ist. Wenn die Aufgabe abgeschlossen ist, versucht sie, den Thread-Kontext, in dem sie gestartet wurde, erneut einzugeben, kann dies jedoch nicht, da sich in diesem Kontext bereits ein Thread befindet, der durch den Aufruf vonGetResult()
... Deadlock blockiert wird !In diesem MSDN-Beitrag wird ausführlich beschrieben, wie .NET parallele Threads synchronisiert. Die Antwort auf meine eigene Frage enthält einige bewährte Methoden.
quelle
Nur ein Kopf hoch - wenn Sie das Warten auf der obersten Ebene in einem ASP.NET-Controller verpassen und die Aufgabe anstelle des Ergebnisses als Antwort zurückgeben, hängt sie tatsächlich nur fehlerfrei in den verschachtelten Warteanrufen. Ein dummer Fehler, aber hätte ich diesen Beitrag gesehen, hätte ich mir möglicherweise Zeit gespart, den Code auf etwas Seltsames zu überprüfen.
quelle
Haftungsausschluss: Ich mag die ConfigureAwait () - Lösung nicht, weil ich sie nicht intuitiv und schwer zu merken finde. Stattdessen kam ich zu dem Schluss, nicht erwartete Methodenaufrufe in Task.Run (() => myAsyncMethodNotUsingAwait ()) zu verpacken. Dies scheint zu 100% zu funktionieren, könnte aber nur eine Rennbedingung sein!? Ich bin mir nicht so sicher, was ehrlich sein wird. Diese Schlussfolgerung könnte falsch sein und ich riskiere meine StackOverflow-Punkte hier, um hoffentlich aus den Kommentaren zu lernen :-P. Bitte lesen Sie sie!
Ich hatte gerade das Problem , wie beschrieben und weitere Informationen finden Sie hier .
Die Aussage lautet: "Sie können keine asynchrone Methode aufrufen"
von einer Methode, die blockiert
In meinem Fall konnte ich die aufrufende Methode nicht ändern und sie war nicht asynchron. Aber das Ergebnis war mir eigentlich egal. Soweit ich mich erinnere, hat es auch nicht funktioniert, das .Result zu entfernen und das Warten zu verpassen.
Also habe ich das gemacht:
In meinem Fall war mir das Ergebnis der aufrufenden nicht-asynchronen Methode egal, aber ich denke, das ist in diesem Anwendungsfall ziemlich häufig. Sie können das Ergebnis in der aufrufenden asynchronen Methode verwenden.
quelle