Freigeben über


Asynchrone Programmierung mit Async und Await (Visual Basic)

Mithilfe der asynchronen Programmierung können Sie Leistungsengpässe vermeiden und die Gesamtreaktionsfähigkeit Ihrer Anwendung verbessern. Herkömmliche Techniken zum Schreiben asynchroner Anwendungen können jedoch kompliziert sein, wodurch sie schwer zu schreiben, zu debuggen und zu verwalten sind.

Visual Studio 2012 hat einen vereinfachten Ansatz eingeführt, eine asynchrone Programmierung, die asynchrone Unterstützung in .NET Framework 4.5 und höher sowie in der Windows-Runtime nutzt. Der Compiler erledigt die schwierige Arbeit, die der Entwickler verwendet hat, und Ihre Anwendung behält eine logische Struktur bei, die dem synchronen Code ähnelt. Daher erhalten Sie alle Vorteile der asynchronen Programmierung mit einem Bruchteil des Aufwands.

Dieses Thema enthält eine Übersicht darüber, wann und wie asynchrone Programmierung verwendet wird, und enthält Links zu Supportthemen, die Details und Beispiele enthalten.

Async verbessert die Reaktionsfähigkeit

Asynchronie ist wichtig für Aktivitäten, die potenziell blockiert werden, z. B. wenn Ihre Anwendung auf das Web zugreift. Der Zugriff auf eine Webressource ist manchmal langsam oder verzögert. Wenn eine solche Aktivität innerhalb eines synchronen Prozesses blockiert wird, muss die gesamte Anwendung warten. In einem asynchronen Prozess kann die Anwendung mit anderen Arbeiten fortfahren, die nicht von der Webressource abhängig sind, bis der potenziell blockierende Vorgang abgeschlossen ist.

Die folgende Tabelle zeigt typische Bereiche, in denen die asynchrone Programmierung die Reaktionsfähigkeit verbessert. Die aufgeführten APIs aus .NET Framework 4.5 und windows-Runtime enthalten Methoden, die die asynchrone Programmierung unterstützen.

Anwendungsbereich Unterstützen von APIs, die asynchrone Methoden enthalten
Webzugriff HttpClient, SyndicationClient
Arbeiten mit Dateien StorageFile, StreamWriter, StreamReader, XmlReader
Arbeiten mit Bildern MediaCapture, BitmapEncoderBitmapDecoder
WCF-Programmierung Synchrone und asynchrone Vorgänge

Asynchronität erweist sich als besonders wertvoll für Anwendungen, die auf den UI-Thread zugreifen, da in der Regel alle UI-bezogenen Aktivitäten denselben Thread gemeinsam nutzen. Wenn ein Prozess in einer synchronen Anwendung blockiert wird, werden alle blockiert. Ihre Anwendung reagiert vorübergehend nicht, und Sie könnten irrtümlicherweise schließen, dass sie fehlgeschlagen ist, obwohl sie gerade nur wartet.

Wenn Sie asynchrone Methoden verwenden, reagiert die Anwendung weiterhin auf die Benutzeroberfläche. Sie können beispielsweise die Größe eines Fensters ändern oder minimieren, oder Sie können die Anwendung schließen, wenn Sie nicht warten möchten, bis es abgeschlossen ist.

Der asynchrone Ansatz fügt das Äquivalent einer automatischen Übertragung zur Liste der Optionen hinzu, die Sie beim Entwerfen asynchroner Vorgänge auswählen können. Das heißt, Sie erhalten alle Vorteile der herkömmlichen asynchronen Programmierung, aber mit viel weniger Aufwand vom Entwickler.

Asynchrone Methoden sind einfacher zu schreiben

Die Schlüsselwörter "Async " und "Await " in Visual Basic sind das Herzstück der asynchronen Programmierung. Mithilfe dieser beiden Schlüsselwörter können Sie Ressourcen in .NET Framework oder der Windows-Runtime verwenden, um eine asynchrone Methode fast so einfach zu erstellen, wie Sie eine synchrone Methode erstellen. Asynchrone Methoden, die Sie mithilfe von Async und Await definieren, werden als asynchrone Methoden bezeichnet.

Das folgende Beispiel zeigt eine asynchrone Methode. Fast alles im Code sollte Ihnen völlig vertraut sein. Die Kommentare nennen die Features, die Sie zum Erstellen der Asynchronie hinzufügen.

Sie finden eine vollständige Windows Presentation Foundation (WPF)-Beispieldatei am Ende dieses Themas, und Sie können das Beispiel aus Async-Beispiel herunterladen: Beispiel aus "Asynchrone Programmierung mit Async und Await".

' Three things to note about writing an Async Function:
'  - The function has an Async modifier.
'  - Its return type is Task or Task(Of T). (See "Return Types" section.)
'  - As a matter of convention, its name ends in "Async".
Async Function AccessTheWebAsync() As Task(Of Integer)
    Using client As New HttpClient()
        ' Call and await separately.
        '  - AccessTheWebAsync can do other things while GetStringAsync is also running.
        '  - getStringTask stores the task we get from the call to GetStringAsync.
        '  - Task(Of String) means it is a task which returns a String when it is done.
        Dim getStringTask As Task(Of String) =
            client.GetStringAsync("https://learn.microsoft.com/dotnet")
        ' You can do other work here that doesn't rely on the string from GetStringAsync.
        DoIndependentWork()
        ' The Await operator suspends AccessTheWebAsync.
        '  - AccessTheWebAsync does not continue until getStringTask is complete.
        '  - Meanwhile, control returns to the caller of AccessTheWebAsync.
        '  - Control resumes here when getStringTask is complete.
        '  - The Await operator then retrieves the String result from getStringTask.
        Dim urlContents As String = Await getStringTask
        ' The Return statement specifies an Integer result.
        ' A method which awaits AccessTheWebAsync receives the Length value.
        Return urlContents.Length

    End Using

End Function

Wenn AccessTheWebAsync keine Arbeit zwischen dem Aufruf von GetStringAsync und dem Abwarten auf dessen Abschluss durchführen kann, können Sie Ihren Code vereinfachen, indem Sie den Aufruf und das Abwarten in der folgenden einzigen Anweisung zusammenfassen.

Dim urlContents As String = Await client.GetStringAsync()

Die folgenden Merkmale fassen zusammen, was das vorherige Beispiel zu einer asynchronen Methode macht:

  • Die Methodensignatur enthält einen Async Modifizierer.

  • Der Name einer asynchronen Methode endet nach Konvention mit einem "Async"-Suffix.

  • Der Rückgabetyp ist einer der folgenden Typen:

    • Task(Of TResult), wenn Ihre Methode eine Rückgabeanweisung hat, in der der Operand den Typ TResult hat.
    • Task wenn die Methode keine Rückgabe-Anweisung hat oder eine Rückgabe-Anweisung ohne Operand aufweist.
    • Sub , wenn Sie einen asynchronen Ereignishandler schreiben.

    Weitere Informationen finden Sie weiter unten in diesem Thema unter "Rückgabetypen und Parameter".

  • Die Methode enthält in der Regel mindestens einen Await-Ausdruck, der einen Punkt markiert, an dem die Methode erst fortgesetzt werden kann, wenn der erwartete asynchrone Vorgang abgeschlossen ist. In der Zwischenzeit wird die Methode angehalten, und die Steuerung kehrt zum Aufrufer der Methode zurück. Im nächsten Abschnitt dieses Themas wird veranschaulicht, was am Unterbrechungspunkt geschieht.

In asynchronen Methoden verwenden Sie die bereitgestellten Schlüsselwörter und Typen, um anzugeben, was Sie tun möchten, und der Compiler erledigt den Rest, einschließlich des Nachverfolgens, was passieren muss, wenn das Steuerelement zu einem Wartepunkt in einer angehaltenen Methode zurückkehrt. Einige Routineprozesse, z. B. Schleifen und Ausnahmebehandlung, können im herkömmlichen asynchronen Code schwer behandelt werden. In einer asynchronen Methode schreiben Sie diese Elemente ähnlich wie in einer synchronen Lösung, und das Problem wird gelöst.

Weitere Informationen zur Asynchronie in früheren Versionen von .NET Framework finden Sie unter "TPL" und "Traditional .NET Framework Asynchronous Programming".

Was geschieht in einer Async-Methode

Das Wichtigste bei der asynchronen Programmierung ist, wie der Steuerungsfluss von Methode zu Methode verschoben wird. Das folgende Diagramm führt Sie durch den Prozess:

Diagramm, das die Ablaufverfolgung eines asynchronen Programms zeigt.

Die Zahlen im Diagramm entsprechen den folgenden Schritten:

  1. Ein Ereignishandler ruft die AccessTheWebAsync asynchrone Methode auf und wartet darauf.

  2. AccessTheWebAsync erstellt eine HttpClient Instanz und ruft die GetStringAsync asynchrone Methode auf, um den Inhalt einer Website als Zeichenfolge herunterzuladen.

  3. Etwas passiert in GetStringAsync, das seinen Fortschritt aussetzt. Vielleicht muss es darauf warten, dass eine Website heruntergeladen wird oder eine andere blockierende Tätigkeit beendet ist. Um das Blockieren von Ressourcen zu vermeiden, GetStringAsync übergibt die Steuerung an seinen Aufrufer, AccessTheWebAsync.

    GetStringAsync gibt einen Task(Of TResult) zurück, wobei TResult eine Zeichenfolge ist und AccessTheWebAsync die Aufgabe der getStringTask Variablen zuweist. Die Aufgabe stellt den laufenden Prozess für den Aufruf von GetStringAsync dar, mit der Festlegung, dass bei Abschluss der Arbeit ein tatsächlicher Zeichenfolgenwert erzeugt wurde.

  4. Da getStringTask noch nicht abgewartet wurde, kann AccessTheWebAsync mit anderen Aufgaben fortfahren, die nicht vom Endergebnis von GetStringAsync abhängig sind. Diese Arbeit wird durch einen Aufruf der synchronen Methode DoIndependentWorkdargestellt.

  5. DoIndependentWork ist eine synchrone Methode, die ihre Arbeit ausführt und zum Aufrufer zurückkehrt.

  6. AccessTheWebAsync hat keine Arbeit mehr, die es ohne ein Ergebnis von getStringTask erledigen kann. AccessTheWebAsync als Nächstes möchte die Methode die Länge der heruntergeladenen Zeichenfolge berechnen und zurückgeben, aber sie kann diesen Wert erst berechnen, wenn sie die Zeichenfolge erhält.

    Daher verwendet AccessTheWebAsync einen Await-Operator, um seinen Fortschritt auszusetzen und die Kontrolle an die aufrufende AccessTheWebAsync-Methode zu übergeben. AccessTheWebAsync gibt einen Task(Of Integer) an den Aufrufer zurück. Die Aufgabe stellt eine Zusage dar, um ein ganzzahliges Ergebnis zu erzeugen, das die Länge der heruntergeladenen Zeichenfolge darstellt.

    Hinweis

    Wenn GetStringAsync (und daher getStringTask) abgeschlossen wird, bevor AccessTheWebAsync darauf wartet, verbleibt die Steuerung in AccessTheWebAsync. Die Kosten für das Aussetzen und anschließende Zurückkehren zu AccessTheWebAsync wären verschwendet, wenn der aufgerufene asynchrone Prozess (getStringTask) bereits abgeschlossen ist und AccessTheWebSync nicht auf das endgültige Ergebnis warten müsste.

    Innerhalb des Aufrufers (der Ereignishandler in diesem Beispiel) wird das Verarbeitungsmuster fortgesetzt. Der Anrufer könnte andere Arbeiten ausführen, die nicht vom Ergebnis AccessTheWebAsync abhängig sind, bevor er darauf wartet, oder der Anrufer könnte sofort darauf warten. Der Ereignishandler wartet auf AccessTheWebAsync, und AccessTheWebAsync wartet auf GetStringAsync.

  7. GetStringAsync vervollständigt und liefert ein Ergebnis als Zeichenfolge. Das Zeichenfolgenergebnis wird vom Aufruf GetStringAsync nicht wie erwartet zurückgegeben. (Denken Sie daran, dass die Methode bereits einen Vorgang in Schritt 3 zurückgegeben hat.) Stattdessen wird das Zeichenfolgenergebnis in der Aufgabe gespeichert, die den Abschluss der Methode darstellt. getStringTask Der await-Operator ruft das Ergebnis von getStringTask ab. Die Zuweisungsanweisung weist das abgerufene Ergebnis urlContents zu.

  8. Wenn AccessTheWebAsync das Zeichenfolgenergebnis vorliegt, kann die Methode die Länge der Zeichenfolge berechnen. Dann ist die Arbeit von AccessTheWebAsync auch abgeschlossen, und der wartende Ereignishandler kann fortfahren. Im vollständigen Beispiel am Ende des Themas können Sie überprüfen, ob der Ereignishandler den Wert des Längenergebnisses abruft und druckt.

Wenn Sie neu in der asynchronen Programmierung sind, nehmen Sie sich einen Moment Zeit, um den Unterschied zwischen synchronem und asynchronem Verhalten zu verstehen. Eine synchrone Methode gibt zurück, wenn ihre Arbeit abgeschlossen ist (Schritt 5), aber eine asynchrone Methode gibt einen Vorgangswert zurück, wenn die Arbeit angehalten wird (Schritte 3 und 6). Wenn die asynchrone Methode schließlich ihre Arbeit abgeschlossen hat, wird die Aufgabe als abgeschlossen markiert, und das Ergebnis (falls vorhanden) wird in der Aufgabe gespeichert.

Weitere Informationen zum Steuerungsfluss finden Sie unter "Steuerungsfluss in Asynchronen Programmen (Visual Basic)".

API Async-Methoden

Möglicherweise fragen Sie sich, wo Sie Methoden wie GetStringAsync finden, die die asynchrone Programmierung unterstützen. Die .NET Framework 4.5 oder höher enthält viele Elemente, die mit Async und Await arbeiten. Sie können diese Member durch das Suffix "Async" erkennen, das an den Membernamen angefügt ist, sowie einem Rückgabetyp von Task oder Task(Of TResult). Die Klasse, z. B., enthält Methoden wie System.IO.Stream, CopyToAsync und ReadAsync neben den synchronen Methoden WriteAsync, CopyTo und Read.

Die Windows-Runtime enthält auch viele Methoden, die Sie mit Async und Await in Windows-Apps verwenden können. Weitere Informationen und Beispielmethoden finden Sie unter Aufrufen asynchroner APIs in C# oder Visual Basic, asynchroner Programmierung (Windows-Runtime-Apps) und WhenAny: Bridging zwischen .NET Framework und der Windows-Runtime.

Fäden

Asynchrone Methoden sollen nicht blockierende Vorgänge sein. Ein Await Ausdruck in einer asynchronen Methode blockiert den aktuellen Thread nicht, während die erwartete Aufgabe ausgeführt wird. Stattdessen meldet der Ausdruck den Rest der Methode als Fortsetzung an und gibt die Kontrolle an den Aufrufer der asynchronen Methode zurück.

Die Async Schlüsselwörter Await führen nicht dazu, dass zusätzliche Threads erstellt werden. Asynchrone Methoden erfordern kein Multithreading, da eine asynchrone Methode nicht in einem eigenen Thread ausgeführt wird. Die Methode wird im aktuellen Synchronisierungskontext ausgeführt und verwendet nur Zeit auf dem Thread, wenn die Methode aktiv ist. Sie können Task.Run verwenden, um CPU-gebundene Arbeit in einen Hintergrundthread zu verschieben, aber ein Hintergrundthread hilft nicht bei einem Prozess, der nur darauf wartet, dass die Ergebnisse verfügbar sind.

Der auf Asynchronität basierende Ansatz ist in fast jedem Fall den vorhandenen Ansätzen vorzuziehen. Insbesondere eignet sich dieser Ansatz besser für E/A-gebundene Vorgänge als BackgroundWorker, da der Code einfacher ist und kein Schutz vor Racebedingungen erforderlich ist. In Kombination mit Task.Run ist die asynchrone Programmierung besser als BackgroundWorker für CPU-gebundene Vorgänge, da sie die Koordinationsdetails des Ausführens von Code von der Arbeit trennt, die Task.Run an den Threadpool übertragen wird.

Async und Await

Wenn Sie angeben, dass eine Methode eine asynchrone Methode ist, indem Sie einen Asynchronen Modifizierer verwenden, aktivieren Sie die folgenden beiden Funktionen.

  • Die markierte asynchrone Methode kann Await verwenden, um Anhaltepunkte festzulegen. Der Await-Operator teilt dem Compiler mit, dass die asynchrone Methode nicht über diesen Punkt fortgesetzt werden kann, bis der erwartete asynchrone Prozess abgeschlossen ist. In der Zwischenzeit geht die Kontrolle an den Aufrufer der asynchronen Methode zurück.

    Das Anhalten einer asynchronen Methode bei einem Await Ausdruck stellt keine Beendigung der Methode dar, und Finally Blöcke werden nicht ausgeführt.

  • Auf die markierte Async-Methode können auch Methoden warten, die sie aufrufen.

Eine asynchrone Methode enthält in der Regel ein oder mehrere Vorkommen eines Await Operators, aber das Fehlen von Await Ausdrücken verursacht keinen Compilerfehler. Wenn eine asynchrone Methode keinen Operator zum Markieren eines Anhaltepunkts verwendet Await , wird die Methode trotz des Async Modifizierers als synchrone Methode ausgeführt. Der Compiler gibt eine Warnung für solche Methoden aus.

Async und Await sind kontextbezogene Schlüsselwörter. Weitere Informationen und Beispiele finden Sie in den folgenden Themen:

Rückgabetypen und Parameter

Bei der .NET Framework-Programmierung gibt eine asynchrone Methode in der Regel eine Task oder eine Task(Of TResult)-Methode zurück. Innerhalb einer asynchronen Methode wird ein Await Operator auf eine Aufgabe angewendet, die von einem Aufruf an eine andere asynchrone Methode zurückgegeben wird.

Sie geben Task(Of TResult) als Rückgabetyp an, wenn die Methode eine Return-Anweisung enthält, die einen Operanden vom Typ TResultangibt.

Sie verwenden Task als Rückgabetyp, wenn die Methode keine Rückgabe-Anweisung hat oder eine Rückgabe-Anweisung hat, die keinen Operanden zurückgibt.

Das folgende Beispiel zeigt, wie Sie eine Methode deklarieren und aufrufen, die entweder eine Task(Of TResult) oder ein Task zurückgibt.

' Signature specifies Task(Of Integer)
Async Function TaskOfTResult_MethodAsync() As Task(Of Integer)

    Dim hours As Integer
    ' . . .
    ' Return statement specifies an integer result.
    Return hours
End Function

' Calls to TaskOfTResult_MethodAsync
Dim returnedTaskTResult As Task(Of Integer) = TaskOfTResult_MethodAsync()
Dim intResult As Integer = Await returnedTaskTResult
' or, in a single statement
Dim intResult As Integer = Await TaskOfTResult_MethodAsync()

' Signature specifies Task
Async Function Task_MethodAsync() As Task

    ' . . .
    ' The method has no return statement.
End Function

' Calls to Task_MethodAsync
Task returnedTask = Task_MethodAsync()
Await returnedTask
' or, in a single statement
Await Task_MethodAsync()

Jede zurückgegebene Aufgabe stellt laufende Arbeit dar. Eine Aufgabe umfasst Informationen über den Status des asynchronen Prozesses und schließlich entweder das endgültige Ergebnis des Prozesses oder die Fehlerausnahme, die der Prozess auslöst, falls er nicht erfolgreich ist.

Eine asynchrone Methode kann auch eine Sub Methode sein. Dieser Rückgabetyp wird in erster Linie verwendet, um Ereignishandler zu definieren, bei denen ein Rückgabetyp erforderlich ist. Asynchrone Ereignishandler dienen häufig als Ausgangspunkt für asynchrone Programme.

Eine asynchrone Methode, bei der es sich um eine Sub-Prozedur handelt, kann nicht abgewartet werden, und der Aufrufer kann keine Ausnahmen erfassen, die die Methode auswirft.

Eine asynchrone Methode kann ByRef-Parameter nicht deklarieren, aber die Methode kann Methoden aufrufen, die über solche Parameter verfügen.

Weitere Informationen und Beispiele finden Sie unter Async-Rückgabetypen (Visual Basic). Weitere Informationen zum Auffangen von Ausnahmen in async-Methoden finden Sie unter Try...Catch...Finally Statement (Try...Catch...Finally-Anweisung).

Asynchrone APIs in der Windows-Runtime-Programmierung weisen einen der folgenden Rückgabetypen auf, die mit Aufgaben vergleichbar sind:

Weitere Informationen und ein Beispiel finden Sie unter Aufrufen asynchroner APIs in C# oder Visual Basic.

Namenskonvention

Standardmäßig fügen Sie "Async" an die Namen von Methoden an, die über einen Async Modifizierer verfügen.

Sie können die Konvention ignorieren, in der ein Ereignis, eine Basisklasse oder ein Schnittstellenvertrag einen anderen Namen vorschlägt. Zum Beispiel sollten Sie keine allgemeinen Ereignishandler wie Button1_Click umbenennen.

Verwandte Themen und Beispiele (Visual Studio)

Titel BESCHREIBUNG Beispiel
Exemplarische Vorgehensweise: Zugreifen auf das Web mithilfe von Async und Await (Visual Basic) Zeigt, wie eine synchrone WPF-Lösung in eine asynchrone WPF-Lösung konvertiert wird. Die Anwendung lädt eine Reihe von Websites herunter. Asynchrones Beispiel: Asynchrone Programmierung mit Async und Await (Visual Basic)
Vorgehensweise: Erweitern Sie das Async Walkthrough mit Task.WhenAll (Visual Basic) Fügt der vorherigen exemplarischen Vorgehensweise Task.WhenAll hinzu. Die Verwendung von WhenAll startet alle Downloads gleichzeitig.
Vorgehensweise: Erstellen mehrerer Webanforderungen parallel mithilfe von Async und Await (Visual Basic) Veranschaulicht, wie mehrere Vorgänge gleichzeitig gestartet werden. Asynchrones Beispiel: Erstellen mehrerer Webanforderungen parallel
Asynchrone Rückgabetypen (Visual Basic) Veranschaulicht die Typen, die asynchrone Methoden zurückgeben können, und erläutert, wann jeder Typ geeignet ist.
Steuerungsfluss in Async-Programmen (Visual Basic) Verfolgt die Ablaufsteuerung ausführlich durch eine Reihenfolge von await-Ausdrücken in einem asynchronen Programm. Asynchrones Beispiel: Steuerungsfluss in Async-Programmen
Fine-Tuning Ihrer asynchronen Anwendung (Visual Basic) Zeigt, wie Sie Ihrer asynchronen Lösung die folgenden Funktionen hinzufügen:

- Abbrechen einer asynchronen Aufgabe oder einer Aufgabenliste (Visual Basic)
- Asynchrone Aufgaben nach einem Bestimmten Zeitraum abbrechen (Visual Basic)
- Verbleibende asynchrone Aufgaben nach Abschluss eines Vorgangs abbrechen (Visual Basic)
- Starten mehrerer asynchroner Aufgaben und Verarbeiten von Aufgaben während der Ausführung (Visual Basic)
Asynchrones Beispiel: Optimieren Ihrer Anwendung
Ablauf des erneuten Eintretens in asynchronen Anwendungen (Visual Basic) Zeigt, wie Fälle behandelt werden, in denen ein aktiver asynchroner Vorgang während der Ausführung neu gestartet wird.
WhenAny: Überbrückung zwischen .NET Framework und der Windows-Runtime Zeigt, wie Sie zwischen Aufgabentypen im .NET Framework und IAsyncOperations in der Windows-Runtime überbrücken können, damit Sie WhenAny mit einer Windows-Runtime-Methode verwenden. Asynchrones Beispiel: Bridging zwischen .NET und Windows-Runtime (AsTask und WhenAny)
Asynchroner Abbruch: Überbrückung zwischen .NET Framework und Windows-Runtime Zeigt, wie Sie zwischen Aufgabentypen im .NET Framework und IAsyncOperations in der Windows-Runtime überbrücken können, damit Sie CancellationTokenSource mit einer Windows-Runtime-Methode verwenden. Asynchrones Beispiel: Überbrückung zwischen .NET und Windows-Runtime (AsTask & Cancellation)
Verwenden von Async für Dateizugriff (Visual Basic) Listet und demonstriert die Vorteile der Verwendung von async und await, um auf Dateien zuzugreifen.
Aufgabenbasiertes asynchrones Muster (TAP) Beschreibt ein neues Muster für Asynchronie in .NET Framework. Das Muster basiert auf den Typen Task und Task(Of TResult).

Vollständiges Beispiel

Der folgende Code ist die MainWindow.xaml.vb Datei aus der Windows Presentation Foundation (WPF)-Anwendung, die in diesem Thema erläutert wird. Sie können das Beispiel aus dem Async-Beispiel herunterladen: Beispiel aus "Asynchrone Programmierung mit Async und Await".


Imports System.Net.Http

' Example that demonstrates Asynchronous Programming with Async and Await.
' It uses HttpClient.GetStringAsync to download the contents of a website.
' Sample Output:
' Working . . . . . . .
'
' Length of the downloaded string: 39678.

Class MainWindow

    ' Mark the event handler with Async so you can use Await in it.
    Private Async Sub StartButton_Click(sender As Object, e As RoutedEventArgs)

        ' Call and await immediately.
        ' StartButton_Click suspends until AccessTheWebAsync is done.
        Dim contentLength As Integer = Await AccessTheWebAsync()

        ResultsTextBox.Text &= $"{vbCrLf}Length of the downloaded string: {contentLength}.{vbCrLf}"

    End Sub


    ' Three things to note about writing an Async Function:
    '  - The function has an Async modifier.
    '  - Its return type is Task or Task(Of T). (See "Return Types" section.)
    '  - As a matter of convention, its name ends in "Async".
    Async Function AccessTheWebAsync() As Task(Of Integer)

        Using client As New HttpClient()

            ' Call and await separately.
            '  - AccessTheWebAsync can do other things while GetStringAsync is also running.
            '  - getStringTask stores the task we get from the call to GetStringAsync.
            '  - Task(Of String) means it is a task which returns a String when it is done.
            Dim getStringTask As Task(Of String) =
                client.GetStringAsync("https://learn.microsoft.com/dotnet")

            ' You can do other work here that doesn't rely on the string from GetStringAsync.
            DoIndependentWork()

            ' The Await operator suspends AccessTheWebAsync.
            '  - AccessTheWebAsync does not continue until getStringTask is complete.
            '  - Meanwhile, control returns to the caller of AccessTheWebAsync.
            '  - Control resumes here when getStringTask is complete.
            '  - The Await operator then retrieves the String result from getStringTask.
            Dim urlContents As String = Await getStringTask

            ' The Return statement specifies an Integer result.
            ' A method which awaits AccessTheWebAsync receives the Length value.
            Return urlContents.Length

        End Using

    End Function

    Sub DoIndependentWork()
        ResultsTextBox.Text &= $"Working . . . . . . .{vbCrLf}"
    End Sub

End Class

Siehe auch