async (C#-Referenz)

Mit dem async-Modifizierer können Sie angeben, dass eine Methode, ein Lambdaausdruck oder eine anonyme Methode asynchron ist. Wenn Sie diesen Modifizierer auf Methoden oder Ausdrücke anwenden, wird dies als asynchrone Methode bezeichnet. Im folgenden Beispiel wird eine asynchrone Methode mit dem Namen ExampleMethodAsync definiert:

public async Task<int> ExampleMethodAsync()
{
    //...
}

Wenn Sie mit der asynchronen Programmierung noch nicht vertraut sind oder nicht wissen, wie eine Async-Methode den await-Operator verwendet, um Aufgaben mit potenziell langer Laufzeit auszuführen, ohne den Thread des Aufrufers zu blockieren, können Sie sich die Einführung unter Asynchrone Programmierung mit async und await durchlesen. Der folgende Code befindet sich in einer asynchronen Methode und ruft die HttpClient.GetStringAsync-Methode auf:

string contents = await httpClient.GetStringAsync(requestUrl);

Eine asynchrone Methode wird bis zum ersten await-Ausdruck synchron ausgeführt. Dann wird die Methode angehalten, bis die erwartete Aufgabe abgeschlossen ist. In der Zwischenzeit wird die Steuerung an den Aufrufer der Methode zurückgegeben, wie das Beispiel in nächsten Thema zeigt.

Wenn die Methode, die mit dem async-Schlüsselwort geändert wird, keinen await-Ausdruck oder keine await-Anweisung enthält, wird die Methode synchron ausgeführt. Mit einer Compilerwarnung werden Sie auf alle asynchronen Methoden hingewiesen, die keine await-Anweisungen enthalten, da dies möglicherweise auf einen Fehler hindeutet. Siehe Compilerwarnung (Stufe 1) CS4014.

Das async-Schlüsselwort ist insofern kontextabhängig, dass es nur dann ein Schlüsselwort ist, wenn mit ihm eine Methode, ein Lambda-Ausdruck oder eine anonyme Methode geändert wird. In allen anderen Kontexten wird es als Bezeichner interpretiert.

Beispiel

Im folgenden Beispiel werden die Struktur und Ablaufsteuerung zwischen einem asynchronen Ereignishandler, StartButton_Click, und einer asynchronen Methode, ExampleMethodAsync, veranschaulicht. Das Ergebnis der asynchronen Methode ist die Anzahl von Zeichen einer Webseite. Der Code ist für eine Windows Presentation Foundation (WPF)- oder Windows Store-Anwendung geeignet, die Sie in Visual Studio erstellen. Informationen zum Einrichten der Anwendung finden Sie in den Codekommentaren.

Sie können diesen Code in Visual Studio als Windows Presentation Foundation (WPF)-App oder Windows Store-App ausführen. Sie benötigen ein Schaltflächen-Steuerelement mit dem Namen StartButton und ein Textfeldsteuerelement mit dem Namen ResultsTextBox. Denken Sie daran, die Namen und den Handler so festzulegen, dass es in etwa wie folgt aussieht:

<Button Content="Button" HorizontalAlignment="Left" Margin="88,77,0,0" VerticalAlignment="Top" Width="75"
        Click="StartButton_Click" Name="StartButton"/>
<TextBox HorizontalAlignment="Left" Height="137" Margin="88,140,0,0" TextWrapping="Wrap"
         Text="&lt;Enter a URL&gt;" VerticalAlignment="Top" Width="310" Name="ResultsTextBox"/>

So führen Sie den Code als WPF-App aus:

  • Fügen Sie diesen Code in die MainWindow-Klasse in „MainWindow.xaml.cs“ ein.
  • Fügen Sie einen Verweis auf „System.Net.Http“ hinzu.
  • Fügen Sie eine using-Anweisung für „System.Net.Http“ hinzu.

So führen Sie den Code als Windows Store-App aus:

  • Fügen Sie diesen Code in die MainPage-Klasse in „MainPage.xaml.cs“ ein.
  • Fügen Sie using-Anweisungen für „System.Net.Http“ und „System.Threading.Tasks“ hinzu.
private async void StartButton_Click(object sender, RoutedEventArgs e)
{
    // ExampleMethodAsync returns a Task<int>, which means that the method
    // eventually produces an int result. However, ExampleMethodAsync returns
    // the Task<int> value as soon as it reaches an await.
    ResultsTextBox.Text += "\n";

    try
    {
        int length = await ExampleMethodAsync();
        // Note that you could put "await ExampleMethodAsync()" in the next line where
        // "length" is, but due to when '+=' fetches the value of ResultsTextBox, you
        // would not see the global side effect of ExampleMethodAsync setting the text.
        ResultsTextBox.Text += String.Format("Length: {0:N0}\n", length);
    }
    catch (Exception)
    {
        // Process the exception if one occurs.
    }
}

public async Task<int> ExampleMethodAsync()
{
    var httpClient = new HttpClient();
    int exampleInt = (await httpClient.GetStringAsync("http://msdn.microsoft.com")).Length;
    ResultsTextBox.Text += "Preparing to finish ExampleMethodAsync.\n";
    // After the following return statement, any method that's awaiting
    // ExampleMethodAsync (in this case, StartButton_Click) can get the
    // integer result.
    return exampleInt;
}
// The example displays the following output:
// Preparing to finish ExampleMethodAsync.
// Length: 53292

Wichtig

Weitere Informationen zu Aufgaben und zum Code, der während des Wartens auf eine Aufgabe ausgeführt wird, finden Sie unter Asynchrone Programmierung mit async und await. Ein vollständiges Konsolenbeispiel, das ähnliche Elemente verwendet, finden Sie unter Mehrere asynchrone Aufgaben starten und nach Abschluss verarbeiten (C#).

Rückgabetypen

Eine asynchrone Methode kann folgende Rückgabetypen haben:

  • Task
  • Task<TResult>
  • void. Von den async void-Methoden wird außer für Code für Ereignishandler allgemein abgeraten, da aufrufende Funktionen für diese Methoden await nicht verwenden können und einen anderen Mechanismus implementieren müssen, um den erfolgreichen Abschluss oder Fehler zu melden.
  • Jeder Typ verfügt über eine zugängliche GetAwaiter-Methode. Der Typ System.Threading.Tasks.ValueTask<TResult> ist eine solche Implementierung. Er ist verfügbar, wenn Sie das NuGet-Paket System.Threading.Tasks.Extensions hinzufügen.

Mit der asynchronen Methode können keine in-, ref- oder out-Parameter deklariert werden, und sie kann auch keinen Verweisrückgabewert aufweisen, es können mit ihr jedoch Methoden aufgerufen werden, die solche Parameter aufweisen.

Task<TResult> wird als Rückgabetyp einer Async-Methode angegeben, wenn mit der return-Anweisung der Methode ein Operand vom Typ TResult angegeben wird. Task wird verwendet, falls kein sinnvoller Wert zurückgegeben wird, wenn die Methode abgeschlossen ist. Das bedeutet, dass ein Aufruf der Methode einen Task zurückgibt. Wenn der Task aber abgeschlossen ist, wird jeder await-Ausdruck, der auf den Task wartet, als void ausgewertet.

Der Rückgabetyp void wird hauptsächlich zum Definieren von Ereignishandlern verwendet, die diesen Rückgabetyp erfordern. Der Aufrufer einer Async-Methode, die void zurückgibt, kann auf ihn nicht warten und keine Ausnahmen auffangen, die von der Methode ausgelöst werden.

Sie geben einen anderen Typ zurück, üblicherweise ein Werttyp, der über eine GetAwaiter-Methode zum Minimieren von Speicherbelegungen verfügt, die für die Leistung entscheidend sind.

Weitere Informationen und Beispiele finden Sie unter Asynchrone Rückgabetypen.

Siehe auch