Ich versuche zu verstehen, wie Async und Await funktionieren. Wie steuern Reisen im Programm. Hier ist der Code, den ich zu verstehen versuchte.
%Vor% Wenn ein Knopfklick erfolgt, wird MyMethod()
aufgerufen und von MyMethod LongRunningOperation()
wird aufgerufen und es dauert 5 Sekunden bis zum Abschluss. also meine Frage ist
Was bedeutet diese Zeile?
Task longRunningTask = LongRunningOperation ();
Was das bedeutet int result = await longRunningTask;
Die obige Zeile könnte festgeschrieben werden und eine Zeile wie
%Vor%oder
%Vor%1) Wenn die longRunningOperation noch nicht beendet ist und noch läuft, kehrt MyMethod () zu seiner aufrufenden Methode zurück, wodurch der Hauptthread nicht blockiert wird. Wenn die longRunningOperation abgeschlossen ist, kehrt ein Thread vom ThreadPool (kann ein beliebiger Thread sein) zu MyMethod () im vorherigen Zustand zurück und setzt die Ausführung fort (in diesem Fall wird das Ergebnis an die Konsole ausgegeben).
Ein zweiter Fall wäre, dass die longRunningOperation ihre Ausführung bereits beendet hat und das Ergebnis verfügbar ist. Wenn der Compiler longRunningOperation erreicht, weiß der Compiler, dass er das Ergebnis hat und weiterhin Code auf demselben Thread ausführen wird. (In diesem Fall Druckergebnis zur Konsole).
Punkt 1 ist mir gar nicht klar wie die Aussage " if the longRunningOperation hasn't finished and is still running, MyMethod() will return to its calling method
"
Wenn möglich, erläutern Sie den Punkt genauer. Danke
Ich habe eine async
Einführung in meinem Blog, die Sie vielleicht hilfreich finden .
Dieser Code:
%Vor%ist im Wesentlichen dasselbe wie dieser Code:
%Vor% Also, ja, LongRunningOperation
wird direkt von dieser Methode aufgerufen.
Wenn dem Operator await
eine bereits abgeschlossene Aufgabe übergeben wird, wird das Ergebnis extrahiert und die Methode (synchron) ausgeführt.
Wenn dem Operator await
eine unvollständige Aufgabe übergeben wurde (z. B. ist die von LongRunningOperation
zurückgegebene Aufgabe nicht abgeschlossen), erfasst await
standardmäßig den aktuellen Kontext und gibt eine unvollständige Aufgabe von der Methode zurück.
Später, wenn die await
Aufgabe abgeschlossen ist, wird der Rest der Methode in diesem Kontext ausgeführt.
Dieser "Kontext" ist SynchronizationContext.Current
, es sei denn, es ist null
, in diesem Fall ist es TaskScheduler.Current
. Wenn Sie dies in einer Konsolenanwendung ausführen, ist der Kontext normalerweise der Threadpoolkontext. Daher wird die Methode async
die Ausführung in einem Threadpool-Thread fortsetzen. Wenn Sie jedoch die gleiche Methode für einen Benutzeroberflächenthread ausführen, ist der Kontext ein UI-Kontext, und die async
-Methode wird wieder im UI-Thread ausgeführt.
Ich habe es auf die folgende Weise gelernt, ich fand es eine klare und prägnante Erklärung:
%Vor% Wenn Method
aufgerufen wird, wird der Inhalt ( code;
lines) bis await something;
ausgeführt. An diesem Punkt wird something;
ausgelöst und die Methode endet wie ein return;
war dort.
something;
tut was es braucht und kehrt dann zurück.
Wenn something;
zurückkehrt, kehrt die Ausführung zu Method
zurück und läuft von await
weiter, wobei moreCode;
In noch mehr schematischer Weise passiert hier Folgendes:
code;
wird ausgeführt something;
wird ausgeführt, der Ablauf kehrt zu dem Punkt zurück, an dem Method
aufgerufen wurde Method
Aufruf something;
zurückgibt, kehrt der Ablauf in Method
zurück
moreCode;
wird ausgeführt und Method
selbst endet (ja, es könnte auch etwas anderes await
-ing geben, und so weiter) Hinter den Kulissen konvertiert der C # -Compiler Ihren Code in eine Zustandsmaschine. Es erzeugt viel mehr Code, so dass hinter den Kulissen jedes Mal, wenn eine wartende Aufgabe oder eine asynchrone Aktion abgeschlossen wird, die Ausführung dort fortgesetzt wird, wo sie aufgehört hat. In Bezug auf Ihre Frage wird die asynchrone Methode jedes Mal, wenn die asynchrone Aktion beendet ist, beim aufrufenden Thread aufgerufen, wenn Sie den Aufruf der asynchronen Methode ursprünglich gestartet haben. ZB wird Ihr Code in dem Thread ausgeführt, auf dem Sie begonnen haben. Daher wird die asynchrone Aktion in einem Task-Thread ausgeführt, dann wird das Ergebnis in dem Thread zurückgegeben, in dem die Methode ursprünglich aufgerufen wurde, und weiter ausgeführt.
await ruft den Wert aus der Task oder async Aktion ab und "entpackt" ihn von der Task, wenn die Ausführung zurückgegeben wird. In diesem Fall wird er automatisch in den int Wert gesetzt, so dass die Aufgabe nicht gespeichert werden muss.
Ihr Code hat das Problem, wo er in der LongRunningTask () erwartet wird, dass Sie wahrscheinlich nur die lange Task-Methode ohne den Async zurückgeben möchten, dann lassen Sie Ihre MyMethod die Wartezeit erfüllen.
int Wert = erwartet LongWaitingTask ()
Es ist eine Voraussetzung für asynchrone Methoden, dass Sie eine Aufgabe oder void zurückgeben.
Es ist möglich, es zu ändern, wenn Sie von der Ausführung der asynchronen Task zurückkehren, wird der restliche Code in dem Thread ausgeführt, in dem die asynchrone Task ausgeführt wurde. Ссылка
Tags und Links c# async-await