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 async
wzorcem 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 synchronicznej funkcji lokalnej 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 t
t
to Task<TResult> lub ValueTask<TResult>.TResult
Jeśli typ to t
Task 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ż
- Operatory i wyrażenia języka C#
- async
- Model programowania asynchronicznego zadania
- Programowanie asynchroniczne
- Przewodnik: uzyskiwanie dostępu do sieci Web przy użyciu asynchronicznego i await
- Samouczek: generowanie i używanie strumieni asynchronicznych
- Blog platformy .NET: Jak działa async/await naprawdę w języku C#