operator await — asynchroniczne oczekiwanie na ukończenie zadania

await Operator zawiesza ocenę otaczającej metody asynchronicznej do momentu zakończenia operacji asynchronicznej reprezentowanej przez jego operand. Po zakończeniu await operacji asynchronicznej operator zwraca wynik operacji, jeśli istnieje. await Gdy operator jest stosowany do operandu, który reprezentuje już ukończoną operację, zwraca wynik operacji natychmiast bez zawieszenia metody otaczającej. Operator await nie blokuje wątku, który ocenia metodę async. await Gdy operator zawiesza otaczającą metodę asynchroniową, kontrolka powraca do obiektu wywołującego metodę .

W poniższym przykładzie HttpClient.GetByteArrayAsync metoda zwraca Task<byte[]> wystąpienie, które reprezentuje operację asynchroniczną, która generuje tablicę bajtów po zakończeniu. Dopóki operacja nie zostanie ukończona, await operator zawiesi metodę DownloadDocsMainPageAsync . Po DownloadDocsMainPageAsync wstrzymaniu Main kontrolka jest zwracana do metody , która jest obiektem wywołującym .DownloadDocsMainPageAsync Metoda Main jest wykonywana, dopóki nie potrzebuje wyniku operacji asynchronicznej wykonywanej przez metodę DownloadDocsMainPageAsync . W przypadku GetByteArrayAsync pobierania wszystkich bajtów reszta DownloadDocsMainPageAsync metody jest obliczana. Następnie zostanie obliczona pozostała część Main metody.

public class AwaitOperator
{
    public static async Task Main()
    {
        Task<int> downloading = DownloadDocsMainPageAsync();
        Console.WriteLine($"{nameof(Main)}: Launched downloading.");

        int bytesLoaded = await downloading;
        Console.WriteLine($"{nameof(Main)}: Downloaded {bytesLoaded} bytes.");
    }

    private static async Task<int> DownloadDocsMainPageAsync()
    {
        Console.WriteLine($"{nameof(DownloadDocsMainPageAsync)}: About to start downloading.");

        var client = new HttpClient();
        byte[] content = await client.GetByteArrayAsync("https://learn.microsoft.com/en-us/");

        Console.WriteLine($"{nameof(DownloadDocsMainPageAsync)}: Finished downloading.");
        return content.Length;
    }
}
// Output similar to:
// DownloadDocsMainPageAsync: About to start downloading.
// Main: Launched downloading.
// DownloadDocsMainPageAsync: Finished downloading.
// Main: Downloaded 27700 bytes.

Operand await wyrażenia musi podać powiadomienie po zakończeniu zadania. Ogólnie rzecz biorąc, delegat jest wywoływany po pomyślnym lub nieudanym zakończeniu zadania. Sekcja await specyfikacji języka C# zawiera szczegółowe informacje na temat sposobu implementacji tych powiadomień.

W poprzednim przykładzie użyto metody asyncMain. Aby uzyskać więcej informacji, zobacz operator await w sekcji Metoda Main.

Uwaga

Aby zapoznać się z wprowadzeniem do programowania asynchronicznego, zobacz Asynchroniczne programowanie za pomocą asynchronicznego i await. Programowanie asynchroniczne z i await jest zgodne ze asyncwzorcem asynchronicznym opartym na zadaniach.

Operator można używać await tylko w metodzie, wyrażeniu lambda lub metodzie anonimowej , która jest modyfikowana przez słowo kluczowe asynchroniczne . W metodzie asynchronicznej nie można użyć await operatora w treści funkcji synchronicznej wewnątrz bloku instrukcji lock i w niebezpiecznym kontekście.

Operand await operatora jest zwykle jednym z następujących typów platformy .NET: Task, , Task<TResult>ValueTasklub ValueTask<TResult>. Jednak każde oczekiwane wyrażenie może być operandem await operatora. Aby uzyskać więcej informacji, zobacz sekcję Awaitable expressions (Oczekiwano wyrażeń) specyfikacji języka C#.

Typ wyrażenia ma wartość , jeśli typ wyrażenia await tt to Task<TResult> lub ValueTask<TResult>.TResult Jeśli typ to tTask lub ValueTask, typ await t to void. W obu przypadkach, jeśli t zgłosi wyjątek, await t ponownie wywróci wyjątek.

Strumienie asynchroniczne i jednorazowe

Instrukcja służy await foreach do używania asynchronicznego strumienia danych. Aby uzyskać więcej informacji, zobacz sekcję foreach instrukcji iteracji artykułu.

Instrukcja służy await using do pracy z asynchronicznie jednorazowym obiektem, czyli obiektem typu implementujący IAsyncDisposable interfejs. Aby uzyskać więcej informacji, zobacz sekcję Using async unieszkodliwiania artykułu Implement a disposeAsync method (Implementowanie metody DisposeAsync).

operator await w metodzie Main

Main Metoda, która jest punktem wejścia aplikacji, może zwrócić Task lub Task<int>, umożliwiając jej asynchronizowanie, aby można było użyć await operatora w jego treści. We wcześniejszych wersjach języka C#, aby upewnić się, że Main metoda czeka na ukończenie operacji asynchronicznej, możesz pobrać wartość Task<TResult>.Result właściwości Task<TResult> wystąpienia zwróconego przez odpowiednią metodę asynchroniczną. W przypadku operacji asynchronicznych, które nie generują wartości, można wywołać metodę Task.Wait . Aby uzyskać informacje na temat wybierania wersji językowej, zobacz Przechowywanie wersji języka C#.

specyfikacja języka C#

Aby uzyskać więcej informacji, zobacz sekcję Await expressions ( Wyrażenia Await) specyfikacji języka C#.

Zobacz też