Winforms Aufruf der asynchronen Methode hängt Programm
Habe ich gearbeitet, um dieses problem für eine Weile, aber jetzt würde ich wirklich gerne verstehen, was schief geht. Ich habe eine ziemlich einfache Anwendung (es ist eine turtoise SVN-plugin für youtrack, aber ich kann das problem reproduzieren mit einer trivialen winforms-app).
Ich habe eine async-Methode ResolveIssue
public async Task<bool> ResolveIssue(Issue issue, int revision, string[] pathList)
{
await Task.Delay(1000);
return true;
}
Alles, was ich zu tun, um ein deadlock rufen Sie diese asynchrone Methode in einem Button
event-handler und rufen Task.Wait
oder Task.Result
, wie diese
private void buttonOk_Click(object sender, System.EventArgs e)
{
var asyncResolvedIssue = api.ResolveIssue(issue, revision, pathList);
if (asyncResolvedIssue.Result) {} //<== deadlock!
}
Jetzt verstehe ich, es ist ziemlich seltsam, um eine async-Methode aktiv und warten Sie nicht darauf, aber warum sollte es erzeugen einen deadlock?!
- Warum die 2 runter Stimmen? Zumindest teilen sich ein Kommentar.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dein problem ist, weil Sie die Blockierung der UI-thread beim Aufruf
.Result
und Sie erzählt die Fortsetzung nachTask.Delay
für die Ausführung auf dem UI-thread. So sind Sie, die Blockierung der Benutzeroberfläche wartet eine Aufgabe, die blockiert ist durch das warten auf die Benutzeroberfläche frei geworden, ein klassischer deadlock.Zwei Lösungen. Stellen Sie zunächst die Taste klicken Sie auf async zu.
Event-Handler sind der einzige Ort, den Sie tun dürfen
async void
.Die andere Möglichkeit ist zu sagen
Task.Delay
es nicht nötig zu haben, den rest der Funktion ausgeführt, die auf dem UI-thread durch EinstellungConfigureAwait(bool)
auf false.Nun die Codezeile nach der
Task.Delay
läuft auf einem threadpool-thread, statt den UI-thread und nicht blockiert werden durch die Tatsache, dass der UI-thread ist derzeit gesperrt.