Was will ich in meinem Programm realisieren, ist die folgende Aufrufliste/Workflow:Deadlock mit Asynchron & warten
- dispatch()
- autorisieren()
- Httppost()
Meine Idee war, dass httpPost()
Async sein wird, während die anderen 2 Methoden nicht-async bleiben. Aber aus irgendeinem Grund würde es für mich nicht funktionieren, wenn ich nicht 2 + 3 machen würde. asynchron. Vielleicht habe ich noch ein paar Missverständnisse.
Zu meinem Verständnis kann ich entweder a) das await
-keyword wenn die Async-Methode aufrufen (dies wird das Verfahren auszusetzen und auch weiterhin nach dem Asynchron-Methode) abgeschlossen ist, oder b) ommit die await
-keyword und stattdessen Aufgabe nennen. Das Ergebnis der asynchronen Methoden gibt einen Wert zurück, der blockiert, bis das Ergebnis verfügbar ist.
Lassen Sie mich Ihnen das Arbeitsbeispiel:
private int dispatch(string options)
{
int res = authorize(options).Result;
return res;
}
static async private Task<int> authorize(string options)
{
string values= getValuesFromOptions(options);
KeyValuePair<int, string> response = await httpPost(url, values);
return 0;
}
public static async Task<KeyValuePair<int, string>> httpPost(string url, List<KeyValuePair<string, string>> parameters)
{
var httpClient = new HttpClient(new HttpClientHandler());
HttpResponseMessage response = await httpClient.PostAsync(url, new FormUrlEncodedContent(parameters));
int code = (int)response.StatusCode;
response.EnsureSuccessStatusCode();
string responseString = await response.Content.ReadAsStringAsync();
return new KeyValuePair<int, string>(code, responseString);
}
Lassen Sie mich Ihnen die nicht -Arbeiten Beispiel:
private int dispatch(string options)
{
int res = authorize(options).Result;
return res;
}
static private int authorize(string options)
{
string values= getValuesFromOptions(options);
Task<KeyValuePair<int, string>> response = httpPost(url, values);
doSomethingWith(response.Result); // execution will hang here forever
return 0;
}
public static async Task<KeyValuePair<int, string>> httpPost(string url, List<KeyValuePair<string, string>> parameters)
{
var httpClient = new HttpClient(new HttpClientHandler());
HttpResponseMessage response = await httpClient.PostAsync(url, new FormUrlEncodedContent(parameters));
int code = (int)response.StatusCode;
response.EnsureSuccessStatusCode();
string responseString = await response.Content.ReadAsStringAsync();
return new KeyValuePair<int, string>(code, responseString);
}
Ich habe auch versucht, alle haben, 3 Methoden non-async und ersetzen die await
s in httpPost
mit .Result
s, aber dann wird es für immer in der Linie hängen HttpResponseMessage response = httpClient.PostAsync(url, new FormUrlEncodedContent(parameters)).Result;
Könnte jemand mich erleuchten und erklären, was mein Fehler ist?
Um zu testen, ob dies die richtige Erklärung ist, nehmen Sie den nicht-funktionierenden Code und ändert jeden „X erwarten“ auf „erwarten X.ConfigureAwait (false)“. Wenn die Erklärung richtig ist, sollte es jetzt funktionieren. Noch ein Hinweis: Sie haben eine SynchronizationContext, wenn Sie in ASP.Net oder in einer UI-Anwendung ausführen. Wenn ja, vergleichen Sie das Ausführen desselben Codes in einem eigenständigen Konsolenprojekt. – danarmak
@servy: Was ich jedoch nicht verstehe, ist der tatsächliche Unterschied zwischen meinem Arbeitsbeispiel und dem nicht funktionierenden Beispiel. Ich verstehe, dass Sie sagen "erwarten" plant eine Fortsetzung während ".Result" einfach nur Blöcke (ist das so?), Aber würde dies nicht bedeuten, dass ich eine endlose async-erwarten-Kette brauchte, denn ohne 'erwarten 'würde ich blockieren/deadlock Mein Thema? Ich meine, das erste Beispiel ist * nicht * blockieren in 'int res = autorisieren (Optionen) .Result;', aber das zweite Beispiel blockiert in 'doSomethingWith (response.Result);', warum? – user826955