await (C#-Referenz)await (C# Reference)

Der Operator await wird auf eine Aufgabe in einer asynchronen Methode angewendet, um einen Unterbrechungspunkt in die Ausführung der Methode einzufügen, bis die Aufgabe abgeschlossen ist.The await operator is applied to a task in an asynchronous method to insert a suspension point in the execution of the method until the awaited task completes. Die Aufgabe stellt derzeit ausgeführte Arbeit dar.The task represents ongoing work.

await kann nur in einer asynchronen Methode verwendet werden, die vom Schlüsselwort async verändert wird.await can only be used in an asynchronous method modified by the async keyword. Eine solche mit dem async-Modifizierer definierte Methode, die in der Regel mindestens einen await-Ausdruck enthält, wird als asynchrone Methode bezeichnet.Such a method, defined by using the async modifier and usually containing one or more await expressions, is referred to as an async method.

Hinweis

Die Schlüsselwörter async und await wurden in C# 5 eingeführt.The async and await keywords were introduced in C# 5. Eine Einführung in die asynchrone Programmierung finden Sie unter Asynchronous Programming with async and await (Asynchrone Programmierung mit „async“ und „await“).For an introduction to async programming, see Asynchronous Programming with async and await.

In der Regel wird die Aufgabe, auf die Sie den Operator await anwenden, von einem Aufruf einer Methode zurückgegeben, die das aufgabenbasierte asynchrone Muster implementiert.The task to which the await operator is applied typically is returned by a call to a method that implements the Task-Based Asynchronous Pattern. Dazu zählen Methoden, die die Objekte Task, Task<TResult> und System.Threading.Tasks.ValueType<TResult> zurückgeben.They include methods that return Task, Task<TResult>, and System.Threading.Tasks.ValueType<TResult> objects.

Im folgenden Beispiel gibt die HttpClient.GetByteArrayAsync-Methode ein Task<byte[]>-Objekt zurück.In the following example, the HttpClient.GetByteArrayAsync method returns a Task<byte[]>. Diese Aufgabe enthält das Versprechen, das tatsächliche Bytearray zu erzeugen, wenn die Aufgabe abgeschlossen ist.The task is a promise to produce the actual byte array when the task is complete. Der await-Operator hält die Ausführung an, bis die Arbeit der Methode GetByteArrayAsync abgeschlossen ist.The await operator suspends execution until the work of the GetByteArrayAsync method is complete. In der Zwischenzeit wird die Steuerung wieder an den Aufrufer von GetPageSizeAsync übergeben.In the meantime, control is returned to the caller of GetPageSizeAsync. Wenn der Task die Ausführung beendet, wird der await-Ausdruck zu einem Bytearray ausgewertet.When the task finishes execution, the await expression evaluates to a byte array.

using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

public class Example
{
   public static void Main()
   {
      string[] args = Environment.GetCommandLineArgs();
      if (args.Length > 1)
         GetPageSizeAsync(args[1]).Wait();
      else
         Console.WriteLine("Enter at least one URL on the command line.");
   }

   private static async Task GetPageSizeAsync(string url)  
   {  
       var client = new HttpClient();  
       var uri = new Uri(Uri.EscapeUriString(url));
       byte[] urlContents = await client.GetByteArrayAsync(uri);
       Console.WriteLine($"{url}: {urlContents.Length/2:N0} characters");  
   }  
}
// The following call from the command line:
//    await1 http://docs.microsoft.com
// displays output like the following: 
//   http://docs.microsoft.com: 7,967 characters


Wichtig

Das vollständige Beispiel finden Sie unter Exemplarische Vorgehensweise: Zugreifen auf das Web mit Async und Await.For the complete example, see Walkthrough: Accessing the Web by Using Async and Await. Sie können das Beispiel aus den Codebeispielen für Entwickler der Microsoft-Website herunterladen.You can download the sample from Developer Code Samples on the Microsoft website. Das Beispiel befindet sich im AsyncWalkthrough_HttpClient-Projekt.The example is in the AsyncWalkthrough_HttpClient project.

Wenn await auf das Ergebnis eines Methodenaufrufs angewendet wird, der Task<TResult> zurückgibt, ist der Typ des await-Ausdrucks TResult, wie im vorherigen Beispiel gezeigt.As shown in the previous example, if await is applied to the result of a method call that returns a Task<TResult>, then the type of the await expression is TResult. Wenn await auf das Ergebnis eines Methodenaufrufs angewendet wird, der Task zurückgibt, ist der Typ des await-Ausdrucks void.If await is applied to the result of a method call that returns a Task, then the type of the await expression is void. Der Unterschied wird im folgenden Beispiel veranschaulicht.The following example illustrates the difference.

// await keyword used with a method that returns a Task<TResult>.  
TResult result = await AsyncMethodThatReturnsTaskTResult();  

// await keyword used with a method that returns a Task.  
await AsyncMethodThatReturnsTask();  

// await keyword used with a method that returns a ValueTask<TResult>.
TResult result = await AsyncMethodThatReturnsValueTaskTResult();

Ein await-Ausdruck blockiert nicht den Thread, auf dem er ausgeführt wird.An await expression does not block the thread on which it is executing. Stattdessen bewirkt er, dass der Compiler den Rest der asynchronen Methode als Fortsetzung der erwarteten Aufgabe registriert.Instead, it causes the compiler to sign up the rest of the async method as a continuation on the awaited task. Die Steuerung wird dann wieder an den Aufrufer der Async-Methode übergeben.Control then returns to the caller of the async method. Wenn die Aufgabe abgeschlossen ist, löst sie ihre Fortsetzung aus, und die Ausführung der asynchronen Methode wird da fortgesetzt, wo sie angehalten wurde.When the task completes, it invokes its continuation, and execution of the async method resumes where it left off.

Ein await-Ausdruck kann nur in seiner einschließenden Methode, einem Lambdaausdruck oder einer anonymen Methode auftreten, die durch einen async-Modifizierer gekennzeichnet sein muss.An await expression can occur only in the body of its enclosing method, lambda expression, or anonymous method, which must be marked with an async modifier. Der Begriff await dient nur in diesem Kontext als Schlüsselwort.The term await serves as a keyword only in that context. In anderen Kontexten wird er als Bezeichner interpretiert.Elsewhere, it is interpreted as an identifier. Innerhalb der Methode, des Lambdaausdrucks oder der anonymen Methode kann ein await-Ausdruck nicht im Textteil einer synchronen Funktion, einem Abfrageausdruck, im Block einer lock-Anweisung oder in einem unsicheren Kontext auftreten.Within the method, lambda expression, or anonymous method, an await expression cannot occur in the body of a synchronous function, in a query expression, in the block of a lock statement, or in an unsafe context.

AusnahmenExceptions

Die meisten asynchronen Methoden geben einen Task oder Task<TResult> zurück.Most async methods return a Task or Task<TResult>. Die Eigenschaften der zurückgegebenen Aufgabe enthalten Informationen über den Status und Verlauf, z. B. ob die Aufgabe abgeschlossen ist, ob die asynchrone Methode eine Ausnahme verursacht hat oder abgebrochen wurde, und was das Endergebnis ist.The properties of the returned task carry information about its status and history, such as whether the task is complete, whether the async method caused an exception or was canceled, and what the final result is. Der Operator await greift auf diese Eigenschaften zu, indem er Methoden auf dem von der GetAwaiter-Methode zurückgegebenen Objekt aufruft.The await operator accesses those properties by calling methods on the object returned by the GetAwaiter method.

Wenn Sie auf eine asynchrone Methode warten, die eine Aufgabe zurückgibt und eine Ausnahme verursacht, löst der Operator await die Ausnahme erneut aus.If you await a task-returning async method that causes an exception, the await operator rethrows the exception.

Wenn Sie auf eine asynchrone Methode warten, die eine Aufgabe zurückgibt und abgebrochen wird, löst der Operator await erneut eine OperationCanceledException aus.If you await a task-returning async method that's canceled, the await operator rethrows an OperationCanceledException.

Eine einzelne Aufgabe, die einen Fehlerzustand aufweist, kann verschiedene Ausnahmen auslösen.A single task that is in a faulted state can reflect multiple exceptions. Beispielsweise kann die Aufgabe das Ergebnis eines Aufrufs an Task.WhenAll sein.For example, the task might be the result of a call to Task.WhenAll. Wenn Sie auf eine solche Aufgabe warten, löst die await-Operation nur eine der Ausnahmen erneut aus.When you await such a task, the await operation rethrows only one of the exceptions. Sie können jedoch nicht vorhersagen, welche der Ausnahmen erneut ausgelöst wird.However, you can't predict which of the exceptions is rethrown.

Beispiele für die Fehlerbehandlung in asynchronen Methoden finden Sie unter try-catch.For examples of error handling in async methods, see try-catch.

BeispielExample

Im folgenden Beispiel wird die Gesamtzahl der Zeichen auf den Seiten zurückgegeben, deren URLs als Befehlszeilenargumente übergeben werden.The following example returns the total number of characters in the pages whose URLs are passed to it as command line arguments. Im Beispiel wird die Methode GetPageLengthsAsync aufgerufen, die mit dem Schlüsselwort async gekennzeichnet ist.The example calls the GetPageLengthsAsync method, which is marked with the async keyword. Die Methode GetPageLengthsAsync verwendet wiederum das Schlüsselwort await, um auf Aufrufe der Methode HttpClient.GetStringAsync zu warten.The GetPageLengthsAsync method in turn uses the await keyword to await calls to the HttpClient.GetStringAsync method.

using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

class Example
{
   static void Main()
   {
      string[] args = Environment.GetCommandLineArgs();
      if (args.Length < 2)
         throw new ArgumentNullException("No URLs specified on the command line.");
      
      long characters = GetPageLengthsAsync(args).Result;
      Console.WriteLine($"{args.Length - 1} pages, {characters:N0} characters");
   }

   private static async Task<long> GetPageLengthsAsync(string[] args)
   {
      var client = new HttpClient();
      long pageLengths = 0;

      for (int ctr = 1; ctr < args.Length; ctr++) {
         var uri = new Uri(Uri.EscapeUriString(args[ctr]));
         string pageContents = await client.GetStringAsync(uri);
         Interlocked.Add(ref pageLengths, pageContents.Length);
      }
      return pageLengths;
   }
}

Da die Verwendung von async und await an einem Anwendungseinstiegspunkt nicht unterstützt wird, kann das async-Attribut nicht auf die Main-Methode angewendet werden und es kann auch nicht auf den Methodenaufruf GetPageLengthsAsync gewartet werden.Because the use of async and await in an application entry point is not supported, we cannot apply the async attribute to the Main method, nor can we await the GetPageLengthsAsync method call. Es kann sichergestellt werden, dass die Main-Methode auf den Abschluss des asynchronen Vorgangs wartet, indem der Wert der Eigenschaft Task<TResult>.Result abgerufen wird.We can ensure that the Main method waits for the async operation to complete by retrieving the value of the Task<TResult>.Result property. Bei Aufgaben, die keinen Wert zurückgeben, wird die Methode Task.Wait aufgerufen.For tasks that do not return a value, you can call the Task.Wait method.

Siehe auchSee also

Asynchrone Programmierung mit Async und Await Asynchronous Programming with async and await
Exemplarische Vorgehensweise: Zugreifen auf das Web mit Async und Await Walkthrough: Accessing the Web by Using Async and Await
asyncasync