await (C# リファレンス)await (C# Reference)

await 演算子は非同期メソッドのタスクに適用され、中断ポイントを挿入することで、メソッドの実行を、待機中のタスクが完了するまで中断します。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. このタスクは、進行中の作業を表します。The task represents ongoing work.

await は、async キーワードによって変更された非同期メソッドでのみ使用できます。await can only be used in an asynchronous method modified by the async keyword. このようなメソッド (async 修飾子を使用して定義され、通常 1 つ以上の await 式を含むメソッド) が、"非同期メソッド" と呼ばれます。Such a method, defined by using the async modifier and usually containing one or more await expressions, is referred to as an async method.

注意

async キーワードおよび await キーワードは、C# 5 で導入されました。The async and await keywords were introduced in C# 5. 非同期プログラミングの概要については、「Async および Await を使用した非同期プログラミング」をご覧ください。For an introduction to async programming, see Asynchronous Programming with async and await.

await 演算子を適用するタスクは、通常、タスク ベースの非同期パターンを実装するメソッド呼び出しによって返されます。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. たとえば、TaskTask<TResult>、および System.Threading.Tasks.ValueType<TResult> オブジェクトを返すメソッドです。They include methods that return Task, Task<TResult>, and System.Threading.Tasks.ValueType<TResult> objects.

次の例では、HttpClient.GetByteArrayAsync メソッドは Task<byte[]> を返します。In the following example, the HttpClient.GetByteArrayAsync method returns a Task<byte[]>. これにより、タスクが完了したときに実際のバイト配列が生成されることが保証されます。The task is a promise to produce the actual byte array when the task is complete. await 演算子は、GetByteArrayAsync メソッドの処理が完了するまで実行を中断します。The await operator suspends execution until the work of the GetByteArrayAsync method is complete. その間、コントロールは GetPageSizeAsync の呼び出し元に戻されます。In the meantime, control is returned to the caller of GetPageSizeAsync. タスクの実行が終了すると、await 式はバイト配列に評価されます。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


重要

完全な例については、「チュートリアル: Async と Await を使用した Web へのアクセス」をご覧ください。For the complete example, see Walkthrough: Accessing the Web by Using Async and Await. Microsoft Web サイトの開発者コード サンプルからサンプルをダウンロードできます。You can download the sample from Developer Code Samples on the Microsoft website. この例は AsyncWalkthrough_HttpClient プロジェクトにあります。The example is in the AsyncWalkthrough_HttpClient project.

前の例で示したように、Task<TResult> を返すメソッド呼び出しの結果に await を適用する場合、await 式の型は TResult です。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. Task を返すメソッド呼び出しの結果に await が適用されている場合、await 式の型は 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. この違いを次の例に示します。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();

await 式は、自身が実行されているスレッドをブロックするのではなく、An await expression does not block the thread on which it is executing. 非同期メソッドの残りの部分が待機中のタスクの継続として登録されるようにします。Instead, it causes the compiler to sign up the rest of the async method as a continuation on the awaited task. これによって、コントロールは非同期のメソッドの呼び出し元に戻されます。Control then returns to the caller of the async method. タスクが完了すると、継続が呼び出され、中断したところから非同期メソッドの実行が再開されます。When the task completes, it invokes its continuation, and execution of the async method resumes where it left off.

await 式は、async 修飾子でマークする必要がある外側のメソッド、ラムダ式、または匿名メソッドの本体でのみ使用できます。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. await という用語がキーワードとして機能するのはこのコンテキストだけです。The term await serves as a keyword only in that context. 他の場所では、識別子として解釈されます。Elsewhere, it is interpreted as an identifier. メソッド、ラムダ式、または匿名メソッド内では、await 式は、同期関数、クエリ式、lock ステートメントのブロック、または unsafe コンテキストの本体では使用できません。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.

例外Exceptions

大半の非同期メソッドは、Task または Task<TResult> を返します。Most async methods return a Task or Task<TResult>. 返されるタスクのプロパティには、タスクが完了しているかどうか、非同期メソッドで例外または取り消しが発生したかどうか、最終結果など、その状態および履歴に関する情報が含まれます。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. await 演算子は、GetAwaiter メソッドによって返されたオブジェクトでメソッドを呼び出して、こうしたプロパティにアクセスします。The await operator accesses those properties by calling methods on the object returned by the GetAwaiter method.

タスクを返す非同期メソッドを待機しているときにそのメソッドで例外が発生した場合、await 演算子はその例外を再スローします。If you await a task-returning async method that causes an exception, the await operator rethrows the exception.

タスクを返す非同期メソッドを待機しているときにそのメソッドが取り消された場合、await 演算子は OperationCanceledException を再スローします。If you await a task-returning async method that's canceled, the await operator rethrows an OperationCanceledException.

障害の発生した状態にある単一のタスクで、複数の例外が反映される場合があります。A single task that is in a faulted state can reflect multiple exceptions. たとえば、タスクは Task.WhenAll の呼び出しの結果になることがあります。For example, the task might be the result of a call to Task.WhenAll. このようなタスクを待機すると、await 操作によって 1 つの例外のみが再スローされます。When you await such a task, the await operation rethrows only one of the exceptions. ただし、どの例外が再スローされるかを予測することはできません。However, you can't predict which of the exceptions is rethrown.

非同期メソッドのエラー処理の例については、「try-catch」をご覧ください。For examples of error handling in async methods, see try-catch.

Example

次の例では、URL がコマンド ラインの引数として渡されたページの合計文字数を返します。The following example returns the total number of characters in the pages whose URLs are passed to it as command line arguments. この例は、async キーワードでマークされた GetPageLengthsAsync メソッドを呼び出しています。The example calls the GetPageLengthsAsync method, which is marked with the async keyword. その後、GetPageLengthsAsync メソッドは await キーワードを使用して、HttpClient.GetStringAsync メソッドへの呼び出しを待ちます。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;
   }
}

アプリケーション エントリ ポイントでの async および await の使用はサポートされていないため、async 属性は Main メソッドに適用できません。また、GetPageLengthsAsync メソッド呼び出しを待つこともできません。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. 非同期操作が完了するのを Main メソッドが確実に待つようにするには、Task<TResult>.Result プロパティの値を取得します。We can ensure that the Main method waits for the async operation to complete by retrieving the value of the Task<TResult>.Result property. 値を返さないタスクについては、Task.Wait メソッドを呼び出すことができます。For tasks that do not return a value, you can call the Task.Wait method.

関連項目See also

Async および Await を使用した非同期プログラミング Asynchronous Programming with async and await
チュートリアル: Async と Await を使用した Web へのアクセス Walkthrough: Accessing the Web by Using Async and Await
asyncasync