Lassen Sie mich diese Frage nur mit ein paar Dingen vortragen:
Ich weiß also, dass dies keine Best Practice ist, und niemand braucht mir das zu sagen. Dies ist eher eine Frage, "warum funktioniert das?".
Hier ist meine Frage:
Ich habe eine kleine GUI-Anwendung geschrieben, die zwei Schaltflächen und eine Statusbezeichnung hat. Eine der Schaltflächen reproduziert das Deadlock-Problem mit Sync und Async 100% der Zeit. Die andere Schaltfläche ruft die gleiche async-Methode auf, aber sie ist in eine Task eingebettet, diese funktioniert. Ich weiß, dass dies keine gute Programmierpraxis ist, aber ich möchte verstehen, warum es nicht das gleiche Deadlock-Problem hat. Hier ist der Code:
%Vor% Es funktioniert, weil der buttonWorking_Click
async-Code ( DelayAsync
sowie das async
lambda, das an Task.Run
übergeben wurde) kein aktuelles SynchronizationContext
hat, während der buttonDeadlock_Click
async-Code ( DelayAsync
) ) tut es. Sie können den Unterschied beobachten, indem Sie den Debugger ausführen und SynchronizationContext.Current
beobachten.
Ich erkläre die Details hinter dem Deadlock-Szenario in meinem Blogpost Do not Blockieren Sie den Async-Code .
Szenario eins: Sie sitzen an Ihrem Schreibtisch. Es gibt einen Posteingang. Es ist leer. Plötzlich erscheint ein Stück Papier in Ihrem Posteingang und beschreibt eine Aufgabe. Du springst auf die Füße und rennst herum und machst die Aufgabe. Aber was ist die Aufgabe? Es sagt Folgendes zu tun:
Dieser Workflow verhindert, dass Sie die Arbeit erledigen, da die letzten beiden Schritte in der falschen Reihenfolge sind.
Szenario zwei: Sie sitzen an Ihrem Schreibtisch. Es gibt einen Posteingang. Es ist leer. Plötzlich erscheint ein Stück Papier in Ihrem Posteingang und beschreibt eine Aufgabe. Du springst auf die Füße und rennst herum und machst die Aufgabe. Aber was ist die Aufgabe? Es sagt Folgendes zu tun:
Was sagt Debbie zu dem Blatt Papier? Es sagt:
Dieser Arbeitsablauf ist immer noch schrecklich darin, dass (1) Sie nichts tun, während Sie auf Debbies Wecker warten, und (2) Sie die Zeit von zwei Arbeitern verschwenden, wenn Du könntest einen einzigen Arbeiter haben, der all die Arbeit macht. Arbeiter sind teuer.
Aber dieser Workflow hindert Sie nicht daran, Arbeit zu erledigen eventuell . Es blockiert nicht, weil Sie nicht auf Arbeit warten, die Sie selbst in Zukunft tun werden , Sie warten auf jemand anderen , um die Arbeit zu erledigen.
(Ich stelle fest, dass dies keine exakte Analogie für das ist, was in Ihrem Programm passiert, aber es ist nahe genug, um die Idee zu vermitteln.)
Tags und Links c# async-await task