Synchronisation lernenKontext, asynchron und warten

Die asynchrone Programmierung ist eine Form der parallelen Programmierung, mit der Sie Aufgaben ausführen können, die vom Hauptanwendungsthread getrennt sind, und den Thread dann benachrichtigen, wenn seine Ausführung beendet ist. Mit Asynchronität können Sie Aufgaben ausführen, ohne den Ausführungsfluss oder die Reaktionsfähigkeit Ihrer Anwendung aufhalten zu müssen.

Microsoft hat die parallele Programmierung in .Net Framework unterstützt, um die Vorteile von Multi-Core-Systemen zu nutzen. Sie können Asynchronität nutzen, um die Leistung und Reaktionsfähigkeit Ihrer Anwendung zu verbessern.

Im Wesentlichen gibt es zwei mögliche Arten von Vorgängen in einer Anwendung. Dazu gehören rechnergebundene und E / A-gebundene Operationen. Rechengebundene Operationen sind solche, bei denen die Berechnung in einem separaten Thread ausgeführt werden kann, damit der Hauptthread seine Ausführung fortsetzen kann. Im Gegenteil, E / A-gebundene Operationen sind solche, bei denen sie extern ausgeführt werden und daher den aktuellen Thread nicht blockieren müssen, während die E / A ausgeführt wird.

Synchronisationskontext und Ausführungskontext

Jedem Thread ist ein Kontext zugeordnet - dies wird auch als "aktueller" Kontext bezeichnet - und diese Kontexte können von mehreren Threads gemeinsam genutzt werden. Der ExecutionContext enthält relevante Metadaten der aktuellen Umgebung oder des Kontexts, in dem das Programm ausgeführt wird. Der SynchronizationContext stellt eine Abstraktion dar - er gibt den Ort an, an dem der Code Ihrer Anwendung ausgeführt wird.

Mit einem SynchronizationContext können Sie eine Aufgabe in einen anderen Kontext einreihen. Beachten Sie, dass jeder Thread seinen eigenen SynchronizatonContext haben kann. Die SynchronizationContext-Klasse wurde kürzlich zum System.Threading-Namespace hinzugefügt und erleichtert die Kommunikation zwischen Threads. Weitere Informationen zu SynchronizationContext und ExecutionContext finden Sie hier.

Ein tiefer Tauchgang in Async und Await

Die drei asynchronen Programmiermuster umfassen Folgendes:

  1. Asynchrones Programmiermodell (APM)
  2. Ereignisbasiertes asynchrones Muster (EAP)
  3. Aufgabenbasiertes asynchrones Muster (TAP)

Das neueste, das empfohlene und auch das eleganteste von allen ist das TAP.

Beachten Sie, dass Sie eine Methode mit dem Schlüsselwort "async" markieren können, das void, Task oder Task zurückgibt. Beachten Sie, dass die Ausnahmedetails in der Task-Instanz gespeichert werden, wenn eine Ausnahme in einer asynchronen Methode mit dem Rückgabetyp Task oder Task auftritt.

Wenn im Gegensatz dazu eine Ausnahme in einer asynchronen Methode mit dem Rückgabetyp void auftritt, werden die Ausnahmedetails im SynchronizationContext gespeichert, der zum Zeitpunkt des Aufrufs der asynchronen Methode aktiv war. Im Wesentlichen können Sie Ausnahmen, die in einer asynchronen Methode mit dem Rückgabetyp void ausgelöst wurden, nicht mit Ausnahmebehandlungsroutinen behandeln, die in die asynchrone Methode geschrieben wurden. Aufgrund der unterschiedlichen Semantik für Datenverarbeitung und Fehlerbehandlung ist es ratsam, asynchrone Methoden mit ungültigen Rückgabetypen zu vermeiden, es sei denn, es gibt einen ausreichenden Grund für deren Verwendung.

Wenn Sie das Schlüsselwort "await" in einer asynchronen Methode verwenden, wird die Methode in einer Zustandsmaschine aufgeteilt. Beachten Sie, dass das Schlüsselwort "await" den aktuellen SynchronizationContext erfasst. Sobald die Aufgabe, die mit dem Schlüsselwort "await" erwartet wurde, abgeschlossen ist, wird die Zustandsmaschine fortgesetzt und die Ausführung des Codes in der Aufrufermethode neu gestartet bekannt als Fortsetzung. Wenn die Ausführung des Codes, auf den mit dem Schlüsselwort "await" gewartet wurde, zum Zeitpunkt des Auftretens des Suspendierungspunkts abgeschlossen ist, wird die asynchrone Methode (die als "async" gekennzeichnete Methode) synchron ausgeführt. Wenn die Ausführung des erwarteten Codes nicht abgeschlossen ist, wird ein Fortsetzungsdelegierter an den erwarteten Code angehängt.

Sie können asynchrone Methoden nutzen, die void zurückgeben, um asynchrone Ereignishandler zu erstellen. Die Main-Methode kann nicht mit dem Schlüsselwort "async" markiert werden, da dies der Einstiegspunkt der Anwendung ist. Eine "async" -Main-Methode wird in dem Moment beendet, in dem sie aufgerufen wird. Das Schlüsselwort "await" informiert den Compiler darüber, dass die Methode einen Suspendierungs- und Wiederaufnahmepunkt haben kann. Im Übrigen können Sie das Schlüsselwort "await" nur für eine Methode verwenden, die mit dem Schlüsselwort "async" als asynchron markiert wurde.

Eine aufgerufene asynchrone Methode wird unabhängig vom Rückgabetyp der Methode synchron auf dem aktuellen Thread ausgeführt. Wenn Sie eine Methode mit dem Schlüsselwort "async" als asynchron markieren, teilen Sie dem Compiler lediglich mit, dass die Methode in mehrere Aufgaben aufgeteilt werden kann. Einige dieser Aufgaben werden möglicherweise asynchron ausgeführt. Durch die Aufnahme des Schlüsselworts "async" in eine Methode wird der Methodenaufruf nicht als Teil des Thread-Pools in die Warteschlange gestellt. Die Asynchronität (dh ob eine Methode ein asynchrones Verhalten aufweisen würde) hängt tatsächlich von dem Suspendierungspunkt ab, den Sie in Ihrer Methode mit dem Schlüsselwort "await" angegeben haben. Wenn Sie das Schlüsselwort "await" nicht in eine asynchrone Methode aufnehmen, wird die gesamte Methode synchron ausgeführt.