次の方法で共有


Async および Await を使用した非同期プログラミング (C# および Visual Basic)

パフォーマンスのボトルネックを回避しアプリケーション全体の応答性を向上させるために、非同期プログラミングを使用できます。 ただ、非同期アプリケーションを作成する従来の方法は複雑で、プログラムの作成、デバッグ、保守が困難な場合があります。

Visual Studio 2012 では、.NET Framework 4.5 および Windows ランタイム の非同期サポートを活用した、非同期プログラミングへの簡略化した方法を使用できます。 コンパイラがこれまで開発者が行っていた難しい作業を実行し、アプリケーションは同期コードに類似した論理構造を保持します。 その結果、わずかな作業量で非同期プログラミングのすべての利点を得られます。

このトピックは、次のセクションで構成されています。

  • 非同期による応答性の改善
  • 非同期メソッドの作成の簡素化
  • 非同期メソッドでの動作
  • API の非同期メソッド
  • スレッド
  • Async と Await
  • 戻り値の型およびパラメーター
  • 名前付け規約
  • 関連トピック
  • コード例全体
  • 関連トピック

このトピックでは、非同期プログラミングをいつ、どのように使用するかの概要を紹介します。詳細と例を含むをサポート トピックへのリンクもあります。

非同期による応答性の改善

アプリケーションが Web サイトにアクセスする場合など、ブロックする可能性がある操作には、非同期が必要となります。 Web リソースへのアクセスには、遅延が発生することがあります。 このような操作が同期処理内でブロックされた場合、アプリケーション全体が待機する必要があります。 非同期処理では、ブロックする可能性のあるタスク終了するまで、アプリケーションは Web リソースに依存しない他の操作を続行できます。

非同期プログラミングによって応答性を向上する一般的な領域を、次の表に示します。 .NET Framework 4.5 および Windows ランタイム の API の一覧には、非同期のプログラミングをサポートするメソッドが含まれます。

アプリケーション領域

サポートされている、非同期のメソッドを含む API

Web アクセス

HttpClientSyndicationClient

ファイルの処理

StorageFileStreamWriterStreamReaderXmlReader

イメージの処理

MediaCaptureBitmapEncoderBitmapDecoder

WCF プログラミング

同期操作と非同期操作

非同期性は、UI スレッドにアクセスするアプリケーションに対して特に有効です。これは、すべての UI 関連のアクティビティが一般的に 1 つのスレッドを共有するためです。 同期アプリケーションでは、1 つのプロセスがブロックされるとすべてがブロックされます。 アプリケーションが応答を停止するため、待機状態であるとは考えずに失敗したと結論付けることもあります。

非同期メソッドを使用すると、アプリケーションは UI に応答し続けます。 たとえば、ウィンドウのサイズ変更や最小化を実行したり、アプリケーション処理の完了待たずに、アプリケーションを閉じたりできます。

非同期ベースの方法は、非同期操作を設計する場合に選択できるオプションの一覧に、自動送信に相当するものを追加します。 つまり、開発者の少しの作業量で、従来の非同期プログラミングのすべての利点を取得できます。

非同期メソッドの作成の簡素化

Visual Basic の AsyncAwait のキーワードと、C# の asyncawait のキーワードは非同期プログラミングの中核です。 これら 2 つのキーワードを使用すると、同期メソッドの作成とほぼ同様の容易さで、.NET Framework または Windows ランタイム を使用して非同期メソッドを作成できます。 async および await を使用して定義する非同期メソッドは、async メソッドとして参照されます。

async メソッドの例を次に示します。 コードのほとんどは、見たことのあるものと思います。 コメントは、非同期性を作成するために追加した機能を明示しています。

このトピックの最後に完全なサンプル ファイルがあります。また、「Async Sample: Example from "Asynchronous Programming with Async and Await" (Async のサンプル: Async および Await を使用した非同期プログラミングの例)」からサンプルをダウンロードできます。

' Three things to note in the signature: 
'  - The method has an Async modifier.  
'  - The return type is Task or Task(Of T). (See "Return Types" section.) 
'    Here, it is Task(Of Integer) because the return statement returns an integer. 
'  - The method name ends in "Async."
Async Function AccessTheWebAsync() As Task(Of Integer)

    ' You need to add a reference to System.Net.Http to declare client. 
    Dim client As HttpClient = New HttpClient()

    ' GetStringAsync returns a Task(Of String). That means that when you await the 
    ' task you'll get a string (urlContents). 
    Dim getStringTask As Task(Of String) = client.GetStringAsync("https://msdn.microsoft.com")


    ' You can do work here that doesn't rely on the string from GetStringAsync.
    DoIndependentWork()

    ' The Await operator suspends AccessTheWebAsync. 
    '  - AccessTheWebAsync can't continue until getStringTask is complete. 
    '  - Meanwhile, control returns to the caller of AccessTheWebAsync. 
    '  - Control resumes here when getStringTask is complete.  
    '  - The Await operator then retrieves the string result from getStringTask. 
    Dim urlContents As String = Await getStringTask

    ' The return statement specifies an integer result. 
    ' Any methods that are awaiting AccessTheWebAsync retrieve the length value. 
    Return urlContents.Length
End Function
// Three things to note in the signature: 
//  - The method has an async modifier.  
//  - The return type is Task or Task<T>. (See "Return Types" section.)
//    Here, it is Task<int> because the return statement returns an integer. 
//  - The method name ends in "Async."
async Task<int> AccessTheWebAsync()
{ 
    // You need to add a reference to System.Net.Http to declare client.
    HttpClient client = new HttpClient();

    // GetStringAsync returns a Task<string>. That means that when you await the 
    // task you'll get a string (urlContents).
    Task<string> getStringTask = client.GetStringAsync("https://msdn.microsoft.com");

    // You can do work here that doesn't rely on the string from GetStringAsync.
    DoIndependentWork();

    // The await operator suspends AccessTheWebAsync. 
    //  - AccessTheWebAsync can't continue until getStringTask is complete. 
    //  - Meanwhile, control returns to the caller of AccessTheWebAsync. 
    //  - Control resumes here when getStringTask is complete.  
    //  - The await operator then retrieves the string result from getStringTask. 
    string urlContents = await getStringTask;

    // The return statement specifies an integer result. 
    // Any methods that are awaiting AccessTheWebAsync retrieve the length value. 
    return urlContents.Length;
}

AccessTheWebAsync に GetStringAsync を呼び出してその完了を待機する間で実行できる作業がない場合、次の 1 つのステートメントで呼び出しと待機をするようにコードを簡略化できます。

Dim urlContents As String = Await client.GetStringAsync()
string urlContents = await client.GetStringAsync();

次の特徴は、前の例を非同期のメソッドにするための概略です。

  • メソッド シグネチャは Async または async 修飾子を含みます。

  • 非同期メソッドの名前は、慣例により「Async」というサフィックスで終わります。

  • 戻り値の型は次のいずれかになります:

    • メソッドが、オペランドに TResult 型を持つステートメントを戻す場合、Task

    • メソッドがステートメントを戻さない、またはオペランドを持たないステートメントを戻す場合、Task

    • 非同期のイベント ハンドラーを作成する場合は無効 (Visual Basic の Sub)。

    詳細については、このトピックで後述する「戻り値の型およびパラメーター」を参照してください。

  • メソッドには、通常は 1 つ以上の await 式があり、待機中の非同期操作が完了するまでメソッドを続行できないポイントをマークします。 この間メソッドは中断し、メソッドの呼び出し元にコントロールを戻します。 このトピックの次のセクションでは、中断ポイントで何が発生するかを説明します。

非同期のメソッドでは、指定のキーワードと型を使用して何を実行するかを示すと、コンパイラがその作業を引き継ぎます。作業には、中断されたメソッドの待機ポイントにコントロールが戻された場合に実行される作業を、継続的に追跡することも含まれます。 ループおよび例外処理など一部のルーチンのプロセスは、従来の非同期コードによる操作が困難な場合があります。 非同期のメソッドでは、同期ソリューションの場合と同様にこれらの要素を記述すると、問題が解決します。

.NET Framework の以前のバージョンの非同期性の詳細については、「TPL と従来の .NET Framework 非同期プログラミング」を参照してください。

非同期メソッドでの動作

非同期プログラミングでは理解が必要な最も重要なことは、コントロール フローがどのようにメソッドからのメソッドに移動するかということです。 次の図は、このプロセスについて説明します。

非同期プログラムのトレース

図内の数字は、次の手順の番号に対応しています。

  1. イベント ハンドラーは AccessTheWebAsync 非同期のメソッドを呼び出して待機します。

  2. AccessTheWebAsync は HttpClient インスタンスを作成し、文字列として Web サイトのコンテンツをダウンロードする GetStringAsync 非同期メソッドを呼び出します。

  3. GetStringAsync に何かが発生するとプロセスが中断します。 Web サイトからのダウンロード処理、または他のブロックしているアクティビティを待機する必要が考えられます。 リソースのブロックを回避するために、GetStringAsync は呼び出し元の AccessTheWebAsync にコントロールを戻します。

    GetStringAsync は TResult が文字列である Task を返し、AccessTheWebAsync は getStringTask 変数にタスクを割り当てます。 タスクには GetStringAsync への呼び出しの進行中のプロセスを表し、作業が完了すると実際の文字列値を生成するコミットメントがあります。

  4. getStringTask が待機しないため、AccessTheWebAsync は GetStringAsync からの最終結果に依存しない他の作業を続行できます。 この作業は同期メソッド DoIndependentWork への呼び出しによって表されます。

  5. DoIndependentWork は、作業を実行し、呼び出し元に戻る同期メソッドです。

  6. AccessTheWebAsync は getStringTask からの結果なしで実行できる作業を使い果たしました。 AccessTheWebAsync は次に、ダウンロードする文字列の長さを計算しますが、メソッドに文字列が戻されるまで、メソッドはその値を計算できません。

    そのため、AccessTheWebAsync は await 演算子を使用してその進行を中断し、AccessTheWebAsync を呼び出したメソッドにコントロールを戻します。 AccessTheWebAsync は呼び出し元に Task(Of Integer) または Task<int> を返します。 タスクは、ダウンロードされた文字列の長さの整数値を生成することの保証を表します。

    注意

    GetStringAsync (および、結果として getStringTask) が AccessTheWebAsync が待機する前に完了した場合、コントロールは AccessTheWebAsync に残ります。 AccessTheWebAsync を中断して後から戻ることは、呼び出された非同期プロセス (getStringTask) が既に完了していて、AccessTheWebSync が最終結果を待つ必要がない場合に、無駄になることがあります。

    呼び出し元 (この例ではイベント ハンドラー) の内部で、処理パターンが続行されます。 呼び出し元は AccessTheWebAsync からの結果に依存しない他の作業をすることもあり、または直ちに待機状態になることもあります。イベント ハンドラーは AccessTheWebAsync を待機し、AccessTheWebAsync は、GetStringAsync を待機します。

  7. GetStringAsync が完了し、文字列の結果を生成します。 文字列の結果は、GetStringAsync への呼び出しによって、意図した形式では戻されません。(メソッドは既に手順 3. でタスクを戻しています。) 代わりに、文字列の結果は、getStringTask メソッドの完了を示すタスク内に格納されます。 await 演算子は、getStringTask から結果を取得します。 代入ステートメントは urlContents に取得された結果を割り当てます。

  8. AccessTheWebAsync に文字列の結果がある場合、メソッドは文字列の長さを計算できます。 次に AccessTheWebAsync の作業も完了し、待機しているイベント ハンドラーが再開できます。 トピックの最後にある完全なサンプルでは、イベント ハンドラーが長さの結果の値を取得して印刷することを確認できます。

非同期プログラミングの経験がない場合、同期および非同期の動作の違いを、少し時間を割いて考慮してください。 同期メソッドは作業が完了すると戻されます (手順 5.) が、非同期のメソッドは、作業が中断されるとタスクの値を戻します。(手順 3. および 6.) 非同期のメソッドが最終的に作業を完了すると、タスクは完了とマークされ、結果が存在する場合はタスクに格納されます。

コントロール フローの詳細については、「非同期プログラムにおける制御フロー (C# および Visual Basic)」を参照してください。

API の非同期メソッド

非同期のプログラミングをサポートする GetStringAsync などのメソッドがどこにあるのかということです。 .NET Framework 4.5 には async および await と作業する多数のメンバーが含まれています。 メンバー名と Task または Task の戻り値の型に付けられている「Async」というサフィックスでこれらのメンバーを識別できます。 たとえば、System.IO.Stream のクラスには、同期メソッドの CopyToRead、および Write と共に、CopyToAsyncReadAsync、および WriteAsync というメソッドが含まれています。

Windows ランタイム にも Windows ストア アプリケーションの async および await と共に使用できる多くのメソッドがあります。 詳細およびサンプル メソッドについては、「クイック スタート: await 演算子を使用した非同期プログラミング」、「非同期プログラミング (Windows ストア アプリ)」、および「WhenAny: .NET Framework と Windows ランタイム間のブリッジ (C# および Visual Basic)」を参照してください。

スレッド

非同期のメソッドは非ブロッキング操作を意図しています。 非同期のメソッドの await 式は、待機中のタスクの実行中に現在のスレッドをブロックしません。 代わりに、式はメソッドの残りの部分の継続を登録し、非同期のメソッドの呼び出し元にコントロールを戻します。

async および await キーワードは、追加のスレッドを作成する要因にはなりません。 非同期のメソッドは自分自身のスレッドで実行しないため、マルチスレッドは必要ありません。 メソッドは、現在の同期コンテキストで実行し、メソッドがアクティブな場合に限りスレッドの時間を使用します。 Task.Run を使用して、CPU バインディングの作業をバックグラウンド スレッドに移動できますが、バックグラウンド スレッドは、結果を待つだけのプロセスを援助しません。

非同期プログラミングへの非同期ベースのアプローチは、ほぼすべてのケースの既存のアプローチに推奨されます。 特に、このアプローチはコードがシンプルで競合状態からの保護の必要がないため、I/O バインディングの操作では、BackgroundWorker よりも優れています。 Task.Run と組み合わせると、非同期のプログラミングは CPU バインディングの操作に関して BackgroundWorker よりも優れています。非同期のプログラミングは、Task.Run がスレッド プールから移動する作業から、実行するコードの調整の詳細を分離するためです。

Async と Await

Async または async 修飾子を使用して、メソッドが非同期メソッドであることを指定すると、次の 2 つの機能が有効になります。

  • マークされた非同期のメソッドは中断ポイントを示すために Await または await を使用できます。 await 演算子は、非同期のメソッドが、待機中の非同期のプロセスが完了するまでこのポイント以降を続行できないことを、コンパイラに指示します。 その間、コントロールは非同期のメソッドの呼び出し元に戻されます。

    非同期のメソッドの await 式での中断は、メソッドからの終了を意図するものではなく、finally ブロックは実行されません。

  • マークされた非同期のメソッド自体は、呼び出し元のメソッドによって待機できます。

非同期のメソッドには、通常の await 演算子が 1 つ以上ありますが、await 式がない場合もコンパイラ エラーの原因にはなりません。 中断ポイントをマークするために非同期のメソッドが await 演算子を使用しない場合、非同期修飾子が存在しても、メソッドは同期メソッドと同様に実行されます。 このようなメソッドには、コンパイラが警告を発行します。

Async、async、Await、および await は、コンテキスト キーワードです。 詳細およびサンプルについては、次のトピックを参照してください:

戻り値の型およびパラメーター

.NET Framework プログラミングでは、非同期のメソッドは、一般的に Task、または Task を戻します。 非同期のメソッド内で、await 演算子は、他の非同期のメソッドへの呼び出しから戻されたタスクに適用されます。

メソッドが、TResult 型のオペランドを指定する Return (Visual Basic)、または return (C#) ステートメントを含む場合、Task を戻り値の型として指定します。

メソッドに Return ステートメントがない場合、または Return ステートメントがオペランドを戻さない場合、Task を戻り値の型として使用します。

次のサンプルは、Task または Task を戻すメソッドを宣言し、呼び出す方法を示します。

' Signature specifies Task(Of Integer)
Async Function TaskOfTResult_MethodAsync() As Task(Of Integer)

    Dim hours As Integer
    ' . . .
    ' Return statement specifies an integer result.
    Return hours
End Function

' Calls to TaskOfTResult_MethodAsync
Dim returnedTaskTResult As Task(Of Integer) = TaskOfTResult_MethodAsync()
Dim intResult As Integer = Await returnedTaskTResult
' or, in a single statement
Dim intResult As Integer = Await TaskOfTResult_MethodAsync()


' Signature specifies Task
Async Function Task_MethodAsync() As Task

    ' . . .
    ' The method has no return statement.
End Function

' Calls to Task_MethodAsync
Task returnedTask = Task_MethodAsync()
Await returnedTask
' or, in a single statement
Await Task_MethodAsync()
// Signature specifies Task<TResult>
async Task<int> TaskOfTResult_MethodAsync()
{
    int hours;
    // . . .
    // Return statement specifies an integer result.
    return hours;
}

// Calls to TaskOfTResult_MethodAsync
Task<int> returnedTaskTResult = TaskOfTResult_MethodAsync();
int intResult = await returnedTaskTResult;
// or, in a single statement
int intResult = await TaskOfTResult_MethodAsync();


// Signature specifies Task
async Task Task_MethodAsync()
{
    // . . .
    // The method has no return statement.  
}

// Calls to Task_MethodAsync
Task returnedTask = Task_MethodAsync();
await returnedTask;
// or, in a single statement
await Task_MethodAsync();

それぞれ、進行中の作業を示すタスクを戻します。 タスクに非同期処理の状態に関する情報、および最終的にはプロセスからの最終結果、またはプロセスが成功しなかった場合に発生する例外をカプセル化します。

非同期のメソッドは、Sub メソッド (Visual Basic) にもなり、また void 戻り値の型 (C#) を持つこともできます。 この戻り値の型は主として、void の戻り値の型が必要なイベント ハンドラーの定義に使用されます。 非同期のイベント ハンドラーは通常、非同期のプログラムの開始点として機能します。

Sub プロシージャまたは void の戻り値の型を持つ非同期のメソッドは、待機できません。void を戻すメソッドの呼び出し元は、このメソッドがスローする例外をキャッチできません。

非同期のメソッドは、Visual Basic で ByRef パラメーターを宣言できません。また C# で ref または out パラメーターを宣言できません。しかしメソッドは、これらのパラメーターを持つメソッドを呼び出すことはできます。

使用例を含む詳細については、「非同期の戻り値の型 (C# および Visual Basic)」を参照してください。 非同期のメソッドで例外をキャッチする方法の詳細については、「try-catch (C# リファレンス)」、または「Try...Catch...Finally ステートメント (Visual Basic)」を参照してください。

Windows ランタイム プログラミングの非同期 API は、タスクに類似した次のような戻り値の型の 1 つがあります:

詳細およびサンプルついては、「クイック スタート: 非同期プログラミングに await 演算子を使用する」を参照してください。

名前付け規約

慣例により、Async または async の修飾子を持つメソッドの名前には、「Async」を追加します。

イベント、基底クラス、またはインターフェイスのコントラクトが別の名前を表示している場合は、この慣例を無視できます。 たとえば、Button1_Click などの共通のイベント ハンドラーの名前は、変更しないことをお勧めします。

関連トピック

タイトル

説明

サンプル

チュートリアル: Async と Await を使用した Web へのアクセス (C# および Visual Basic)

同期 WPF のソリューションを非同期 WPF のソリューションに変換する方法を示します。 アプリケーションは、一連の Web サイトをダウンロードします。

Async Sample: Accessing the Web Walkthrough (C# and Visual Basic) (非同期のサンプル: Web サイトへのアクセスのチュートリアル (C# および Visual Basic))

方法: Task.WhenAll を使用して AsyncWalkthrough を拡張する (C# および Visual Basic)

前のチュートリアルに Task.WhenAll を追加します。 WhenAll を使用すると、すべてのダウンロードが同時に開始します。

方法: Async と Await を使用して複数の Web 要求を並列実行する (C# および Visual Basic)

複数のタスクを同時に開始する方法を示します。

Async Sample: Make Multiple Web Requests in Parallel (C# and Visual Basic) (非同期のサンプル: 複数の並行 Web 要求の作成 (C# および Visual Basic))

非同期の戻り値の型 (C# および Visual Basic)

非同期のメソッドが戻す型、および各型の適切な使用方法を説明します。

非同期プログラムにおける制御フロー (C# および Visual Basic)

非同期プログラムでの await 式を継続して、コントロールのフローの詳細をトレースします。

Async Sample: Control Flow in Async Programs (C# and Visual Basic) (非同期のサンプル: 非同期のプログラムのコントロール フロー (C# および Visual Basic))

非同期アプリケーションの微調整 (C# および Visual Basic)

非同期のソリューションに次の機能を追加する方法を示します:

Async Sample: Fine Tuning Your Application (C# and Visual Basic) (非同期のサンプル: アプリケーションの微調整 (C# および Visual Basic))

非同期アプリにおける再入の処理 (C# および Visual Basic)

実行中にアクティブな非同期操作を再起動するケースの処理方法を示します。

WhenAny: .NET Framework と Windows ランタイム間のブリッジ (C# および Visual Basic)

Windows ランタイム のメソッドの WhenAny``1 を使用可能にするために、Windows ランタイム で、.NET Framework および IAsyncOperations のタスクの種類間をブリッジする方法を示します。

Async Sample: Bridging between .NET and Windows Runtime (AsTask and WhenAny) (非同期のサンプル: .NET と Windows ランタイム間のブリッジ (AsTask と WhenAny))

非同期のキャンセル: .NET Framework と Windows ランタイム間のブリッジ (C# および Visual Basic)

Windows ランタイム のメソッドの CancellationTokenSource を使用可能にするために、Windows ランタイム で、.NET Framework および IAsyncOperations のタスクの種類間をブリッジする方法を示します。

Async Sample: Bridging between .NET and Windows Runtime (AsTask & Cancellation) (非同期のサンプル: .NET と Windows ランタイム間のブリッジ (AsTask と Cancellation))

ファイル アクセスにおける非同期の使用 (C# および Visual Basic)

async および await を使用してファイルにアクセスすることの利点の一覧と紹介です。

チュートリアル: 非同期メソッドと共にデバッガーを使用する

await ステートメントでのコントロール フロー、非同期メソッドでの [ステップ イン][ステップ オーバー]、および [ステップ アウト] の動作を紹介します。

タスク ベースの非同期パターン (TAP)

.NET Framework での非同期性の新しいパターンについて説明します。 パターンは Task および Task の型に基づいています。

クイック スタート: C# または Visual Basic での非同期 API の呼び出し

Windows ストア アプリで async および await を使用する方法を示します。

非同期プログラミング (Windows ストア アプリ)

Windows ランタイム での非同期プログラミングの概要を説明します。

9 チャネルの非同期に関するビデオ

非同期のプログラミングに関するさまざまなビデオへのリンクを示します。

コード例全体

次のコードは、このトピックで説明する Windows Presentation Foundation (WPF) のアプリケーションの MainWindow.xaml.vb または MainWindow.xaml.cs です。 サンプルは、「Async Sample: Example from "Asynchronous Programming with Async and Await" (非同期のサンプル: 「Async および Await を使用した非同期プログラミング」の例)」からダウンロードできます。

' Add an Imports statement and a reference for System.Net.Http 
Imports System.Net.Http

Class MainWindow

    ' Mark the event handler with async so you can use Await in it. 
    Private Async Sub StartButton_Click(sender As Object, e As RoutedEventArgs)

        ' Call and await separately. 
        'Task<int> getLengthTask = AccessTheWebAsync(); 
        '' You can do independent work here. 
        'int contentLength = await getLengthTask; 

        Dim contentLength As Integer = Await AccessTheWebAsync()

        ResultsTextBox.Text &=
            String.Format(vbCrLf & "Length of the downloaded string: {0}." & vbCrLf, contentLength)
    End Sub 


    ' Three things to note in the signature: 
    '  - The method has an Async modifier.  
    '  - The return type is Task or Task(Of T). (See "Return Types" section.) 
    '    Here, it is Task(Of Integer) because the return statement returns an integer. 
    '  - The method name ends in "Async."
    Async Function AccessTheWebAsync() As Task(Of Integer)

        ' You need to add a reference to System.Net.Http to declare client. 
        Dim client As HttpClient = New HttpClient()

        ' GetStringAsync returns a Task(Of String). That means that when you await the 
        ' task you'll get a string (urlContents). 
        Dim getStringTask As Task(Of String) = client.GetStringAsync("https://msdn.microsoft.com")


        ' You can do work here that doesn't rely on the string from GetStringAsync.
        DoIndependentWork()

        ' The Await operator suspends AccessTheWebAsync. 
        '  - AccessTheWebAsync can't continue until getStringTask is complete. 
        '  - Meanwhile, control returns to the caller of AccessTheWebAsync. 
        '  - Control resumes here when getStringTask is complete.  
        '  - The Await operator then retrieves the string result from getStringTask. 
        Dim urlContents As String = Await getStringTask

        ' The return statement specifies an integer result. 
        ' Any methods that are awaiting AccessTheWebAsync retrieve the length value. 
        Return urlContents.Length
    End Function 


    Sub DoIndependentWork()
        ResultsTextBox.Text &= "Working . . . . . . ." & vbCrLf
    End Sub 
End Class 

' Sample Output: 

' Working . . . . . . . 

' Length of the downloaded string: 41763.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

// Add a using directive and a reference for System.Net.Http; 
using System.Net.Http;

namespace AsyncFirstExample
{
    public partial class MainWindow : Window
    {
        // Mark the event handler with async so you can use await in it. 
        private async void StartButton_Click(object sender, RoutedEventArgs e)
        {
            // Call and await separately. 
            //Task<int> getLengthTask = AccessTheWebAsync(); 
            //// You can do independent work here. 
            //int contentLength = await getLengthTask; 

            int contentLength = await AccessTheWebAsync();

            resultsTextBox.Text +=
                String.Format("\r\nLength of the downloaded string: {0}.\r\n", contentLength);
        }


        // Three things to note in the signature: 
        //  - The method has an async modifier.  
        //  - The return type is Task or Task<T>. (See "Return Types" section.)
        //    Here, it is Task<int> because the return statement returns an integer. 
        //  - The method name ends in "Async."
        async Task<int> AccessTheWebAsync()
        { 
            // You need to add a reference to System.Net.Http to declare client.
            HttpClient client = new HttpClient();

            // GetStringAsync returns a Task<string>. That means that when you await the 
            // task you'll get a string (urlContents).
            Task<string> getStringTask = client.GetStringAsync("https://msdn.microsoft.com");

            // You can do work here that doesn't rely on the string from GetStringAsync.
            DoIndependentWork();

            // The await operator suspends AccessTheWebAsync. 
            //  - AccessTheWebAsync can't continue until getStringTask is complete. 
            //  - Meanwhile, control returns to the caller of AccessTheWebAsync. 
            //  - Control resumes here when getStringTask is complete.  
            //  - The await operator then retrieves the string result from getStringTask. 
            string urlContents = await getStringTask;

            // The return statement specifies an integer result. 
            // Any methods that are awaiting AccessTheWebAsync retrieve the length value. 
            return urlContents.Length;
        }


        void DoIndependentWork()
        {
            resultsTextBox.Text += "Working . . . . . . .\r\n";
        }
    }
}

// Sample Output: 

// Working . . . . . . . 

// Length of the downloaded string: 41564.

参照

関連項目

async (C# リファレンス)

await (C# リファレンス)

Await 演算子 (Visual Basic)

Async (Visual Basic)

その他の技術情報

サンプル: .NET Asynchronous Programming for Windows Store Apps (Windows ストア アプリの .NET 非同期プログラミング方法)

サンプル: Making an await WebClient (await WebClient の作成方法)

サンプル (C#): カスタム オブジェクトのコレクションをローカル ストレージに保存する方法

サンプル (Visual Basic): Save a collection to Application Storage (アプリケーション ストレージにコレクションを保存する方法)