Übersicht über die asynchrone Programmierung
Aktualisiert: November 2007
Eine asynchrone, das IAsyncResult-Entwurfsmuster verwendende Operation wird über zwei Methoden implementiert, die BeginOperationName-Methode und die EndOperationName-Methode, die die asynchrone OperationName-Operation jeweils starten und beenden. Beispielsweise werden von der FileStream-Klasse die BeginRead-Methode und die EndRead-Methode bereitgestellt, um asynchron Bytes aus einer Datei zu lesen. Diese Methoden implementieren die asynchrone Version der Read-Methode.
Nach dem Aufrufen von BeginOperationName kann eine Anwendung mit der Ausführung von Aufgaben im aufrufenden Thread fortfahren, während die asynchrone Operation in einem anderen Thread stattfindet. Mit jedem Aufruf von BeginOperationName muss die Anwendung auch EndOperationName aufrufen, um die Ergebnisse der Operation zu erhalten.
Starten einer asynchronen Operation
Die BeginOperationName-Methode startet die asynchrone OperationName-Operation und gibt ein Objekt zurück, das die IAsyncResult-Schnittstelle implementiert. IAsyncResult-Objekte speichern Informationen über eine asynchrone Operation. In der folgenden Tabelle werden die Informationen über eine asynchrone Operation angezeigt.
Member |
Beschreibung |
---|---|
Ein optionales, anwendungsspezifisches Objekt, das Informationen über die asynchrone Operation enthält. |
|
Ein WaitHandle, das verwendet werden kann, um die Ausführung der Anwendung bis zum Abschluss der asynchronen Operation zu blockieren. |
|
Ein Wert, der angibt, ob die asynchrone Operation für den Thread abgeschlossen wurde, der zum Aufrufen von BeginOperationName verwendet wurde, oder ob die Operation für einen separaten ThreadPool-Thread abgeschlossen wurde. |
|
Ein Wert, der angibt, ob die asynchrone Operation abgeschlossen wurde. |
Eine BeginOperationName-Methode übernimmt alle die in der Signatur der synchronen Version der Methode deklarierten Parameter, die als Wert oder als Verweis übergeben wurden. Keinerlei out-Parameter sind Teil der BeginOperationName-Methodensignatur. Die BeginOperationName-Methodensignatur weist noch zwei zusätzliche Parameter auf. Der erste Parameter definiert einen AsyncCallback-Delegaten, der auf eine Methode verweist, die bei Beendigung der asynchronen Operation aufgerufen wird. Der Aufrufer hat die Möglichkeit, null (Nothing in Visual Basic) festzulegen, wenn bei Abschluss der Operation keine Methode aufgerufen werden soll. Bei dem zweiten, zusätzlichen Parameter handelt es sich um ein benutzerdefiniertes Objekt. Dieses Objekt kann verwendet werden, um bei Abschluss der asynchronen Methode anwendungsspezifische Informationen über den Zustand an die aufgerufene Methode zu übergeben. Falls eine BeginOperationName-Methode zusätzliche, operationsspezifische Parameter übernimmt, z. B. ein Bytearray zum Speichern von Bytes, die aus einer Datei gelesen wurden, dann sind AsyncCallback und das Zustandsobjekt der Anwendung die letzten Parameter in der Signatur der BeginOperationName-Methode.
Starten Von OperationName wird die Steuerung sofort an den aufrufenden Thread zurückgegeben. Wenn die BeginOperationName-Methode Ausnahmen auslöst, dann geschieht dies immer nur vor dem Starten der asynchronen Operation. Wenn die BeginOperationName-Methode Ausnahmen auslöst, wird die Rückrufmethode nicht aufgerufen.
Beenden einer asynchronen Operation
Durch die EndOperationName-Methode wird der asynchrone Vorgang OperationName beendet. Der Rückgabewert der EndOperationName-Methode ist vom selben Typ wie der Rückgabewert des synchronen Pedants dieser Methode und für die asynchrone Operation spezifisch. Beispielsweise gibt die EndRead-Methode die Anzahl der aus einem FileStream gelesenen Bytes und die EndGetHostByName-Methode einIPHostEntry-Objekt zurück, das Informationen über einen Hostcomputer enthält. Von der EndOperationName-Methode wird jeder out-Parameter oder ref-Parameter übernommen, der in der Signatur der synchronen Version der Methode deklariert ist. Zusätzlich zu den Parametern der synchronen Methode enthält die EndOperationName-Methode auch einen IAsyncResult-Parameter. Aufrufer müssen die vom entsprechenden Aufruf von BeginOperationName zurückgegebene Instanz übergeben.
Sollte die durch das IAsyncResult-Objekt dargestellte Operation bei Aufruf von EndOperationName nicht abgeschlossen sein, wird der aufrufende Thread durch EndOperationName bis zum Abschluss dieser asynchronen Operation blockiert. Von der asynchronen Operation ausgelöste Ausnahmen werden von der EndOperationName-Methode ausgelöst. Die Auswirkung des mehrmaligen Aufrufens der EndOperationName-Methode mit dem gleichen IAsyncResult ist nicht definiert. Ebenso undefiniert ist das Aufrufen der EndOperationName-Methode mit einem IAsyncResult, das nicht von der entsprechenden Begin-Methode zurückgegeben wurde.
Hinweis: |
---|
Für beide nicht definierte Szenarien ist von Implementierern das Auslösen der InvalidOperationException in Betracht zu ziehen. |
Hinweis: |
---|
Implementierer dieses Entwurfsmusters sollten den Aufrufer über den Abschluss der asynchronen Operation unterrichten, indem sie IsCompleted auf true festlegen, die asynchrone Rückrufmethode (sofern festgelegt) aufrufen und das AsyncWaitHandle signalisieren. |
Anwendungsentwicklern stehen für den Zugriff auf die Ergebnisse der asynchronen Operation mehrere Auswahlmöglichkeiten beim Entwerfen zur Verfügung. Die richtige Wahl ist davon abhängig, ob in der Anwendung Anweisungen enthalten sind, die bei Abschluss der Operation ausführbar sind. Wenn von einer Anwendung bis zum Erhalt der Ergebnisse der asynchronen Operation keine zusätzlichen Aufgaben ausgeführt werden können, muss die Anwendung solange blockieren, bis die Ergebnisse verfügbar sind. Damit bis zum Abschluss einer asynchronen Operation blockiert wird, können Sie eine der folgenden Vorgehensweisen verfolgen:
Rufen Sie EndOperationName aus dem Hauptthread der Anwendung auf, der die Ausführung der Anwendung bis zum Abschluss der Operation blockiert. Ein Beispiel zu dieser Vorgehensweise finden Sie unter Blockieren der Anwendungsausführung durch Beenden einer asynchronen Methode.
Verwenden Sie das AsyncWaitHandle, um die Ausführung der Anwendung zu blockieren, bis eine oder auch mehrere Operationen abgeschlossen sind. Ein Beispiel zu dieser Vorgehensweise finden Sie unter Blockieren der Anwendungsausführung mithilfe von AsyncWaitHandle.
Für Anwendungen, die bis zum Abschluss der asynchronen Operation nicht blockieren müssen, ist eine der folgenden Vorgehensweisen geeignet:
Rufen Sie den Abschlussstatus der Operation durch periodisches Überprüfen der IsCompleted-Eigenschaft auf, und rufen Sie EndOperationName auf, wenn die Operation abgeschlossen wurde. Ein Beispiel zu dieser Vorgehensweise finden Sie unter Abrufen des Status einer asynchronen Operation.
Verwenden Sie einen AsyncCallback-Delegaten, um eine Methode festzulegen, die nach Abschluss der Operation aufgerufen wird. Ein Beispiel zu dieser Vorgehensweise finden Sie unter Verwenden eines AsyncCallback-Delegaten zum Beenden einer asynchronen Operation.
Siehe auch
Konzepte
Asynchrones Aufrufen von synchronen Methoden
Verwenden von AsyncCallback-Delegat und Zustandsobjekt