Async および Await を使用した非同期プログラミング (C# および Visual Basic)
パフォーマンスのボトルネックを回避し、非同期プログラミングを使用してアプリケーション全体の応答性を向上させることができます。ただし、非同期アプリケーションを作成するための従来の方法は複雑な場合、それらを、書き込みである、デバッグ、保守が困難になります。
Visual Studio 2012 は簡単方法、プログラム .NET Framework 4.5 すると Windows ランタイムの非同期サポートを利用する非同期について説明します。コンパイラがするために使用する開発者が、アプリケーションの同期コードの論理構造を保持する困難な作業を行います。その結果、少量の工数を使用した非同期プログラミングのすべての利点を取得します。
このトピックは、次のセクションで構成されています。
- 非同期操作は応答性が向上します。
- 単一のメソッドは、記述が簡単です
- 発生する内容を単一のメソッドで
- API の単一のメソッド
- Threads
- 非同期操作は、待ち
- 型およびパラメーターを返します。
- 名前付け規約
- 関連トピック
- コード例全体
- 関連トピック
このトピックでは、プログラムする async をいつどのようにビューを使用するように指定し、詳細と例を含むをサポートするトピックへのリンクを示します。
非同期操作は応答性が向上します。
Asynchrony は、アプリケーションがネットワークにアクセスする可能性があるブロックに必要なアクティビティなどです。Web リソースへのアクセスは、または遅延遅くなります。このようなアクティビティが同期処理ブロック内で、アプリケーション全体が待機する必要があります。非同期処理では、アプリケーションは Web リソースに依存しない他の処理とそのタスクをブロックが終了するまで続行できます。
非同期プログラミングが応答性の場所にアップグレードするかを次の表に一般的な領域に示します。.NET Framework 4.5 からリストされた API と Windows ランタイム は非同期のプログラミングをサポートするメソッドが含まれています。
アプリケーション領域 |
非同期のメソッドを含む API サポート |
---|---|
[Web アクセス] |
|
ファイルを使用 |
|
イメージの使用 |
|
WCF プログラミング |
|
ソケットを使用 |
Asynchrony は、すべての UI 関連のアクティビティは一般に、1 種類のスレッドを共有している UI スレッドにアクセスするアプリケーションに対して特に有用検証します。どのプロセスがアプリケーションで同期ブロックは、すべてブロックされます。アプリケーションが応答を停止代わりに、待機しているときに失敗したことによりを及ぼす場合があります。
非同期メソッドを使用すると、アプリケーションは UI に応答し続けます。サイズを変更できますまたは終了するまで待機しない場合は、ウィンドウ (または、を最小限にすると、アプリケーションを閉じることができます。
async ベースの方法は、選択できるオプションのリストに自動変速機同等のものを追加する非同期操作を設計する場合。つまり、開発者から、従来のプログラミングする非同期の少ない労力での利点を取得します。
単一のメソッドは、記述が簡単です
Visual Basic の [Async] と [Await] のキーワードと、C の [async] と 待機します。 のキーワードは非同期プログラミングの中心です。これら二つのキーワードを使用すると、同期メソッドを作成すると、.NET Framework または Windows ランタイム の非同期メソッドを最も簡単に作成するリソースを使用できます。は、定義し、async を使用して待機する非同期メソッドは、非同期のメソッドと呼ばれます。
次の例では、非同期のメソッドを示します。コードのほとんどは、について理解しやすい表示されます。コメントは asynchrony 作成するために追加した機能を明示します。
このトピックの最後に完全なサンプル ファイルを検索サンプルは、単一の例: "Async を使用した非同期プログラミングの例は、待ち"、からダウンロードできます。
' 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 を呼び出し、完了を待つかの間で実行できる作業がない場合、"一つのステートメントを呼び出すと、意図して、コードを簡略化できます。
Dim urlContents As String = Await client.GetStringAsync()
string urlContents = await client.GetStringAsync();
次の特性は前の例と非同期のメソッドにするかを示します。
メソッドのシグネチャは Async または async 修飾子が含まれます。
非同期メソッドの名前は、規則では、"Async" というサフィックスで終わります。
戻り値の型は、次の型の一つです: 1
自分のメソッドにオペランドに TResult 型を持つ return ステートメントがある場合Task<TResult>。
自分のメソッドで、return ステートメントがなく、オペランドを持たない return ステートメントがあるTask。
async のイベント ハンドラーを作成する場合は無効 (Visual Basic の [サブ])。
詳細については、このトピックの "戻り値の型とパラメーター" を参照してください。
メソッドは、通常は 1 文字以上待機しますが、予期した非同期操作が完了するまでメソッドを続行できない点は、式が含まれています。一方、メソッドは、メソッドの呼び出し元に制御が戻る中断されます。発生する可能性中断ポイントでこのトピックの次のセクションで説明します。
非同期のメソッドでは、コントロールが中断されたメソッドの指定の位置に戻るとする、コンパイラは一致する必要があるかを追跡を含む残りを、内容の表示にし、指定されたキーワードと型を使用します。あるルーチンのプロセスは、ループと例外処理など、従来の非同期コードが面倒な場合があります。非同期のメソッドでは、同期ソリューションで、問題を解決するために、これらの要素数を書き込みます。
以前のバージョンの .NET Framework の asynchrony に関する詳細については、TPL と従来の .NET 非同期プログラミングを参照してください。
発生する内容を単一のメソッドで
非同期プログラミングでは理解しておかなければならないは、制御フローがメソッドからのメソッドに渡すことです。次の図は、プロセスについて説明します。
図の数が次のステップに対応します。
イベント ハンドラーは AccessTheWebAsync の非同期のメソッドを呼び出し、待機します。
AccessTheWebAsync は HttpClient のインスタンスを作成し、文字列としてサイトのコンテンツをダウンロードするには GetStringAsync を非同期メソッドを呼び出します。
進行状況を中断することは GetStringAsync で発生します。そのダウンロードするには、Web サイトまたは他のブロックのアクティビティを待機する必要があります。リソースを呼び出し元に、GetStringAsync の yield のコントロール ブロック回避する AccessTheWebAsync。
GetStringAsync は getStringTask の変数に TResult が文字列であると、AccessTheWebAsync タスクの割り当てを返します Task<TResult>。タスクには実際の文字列値をコミットすると GetStringAsyncに作業が完了すると呼び出しの進行中のプロセスを表します。
getStringTask がまだ待機しないため、AccessTheWebAsync は GetStringAsyncから最終結果に依存しない他の作業を続行できます。この作業は同期メソッド DoIndependentWorkの呼び出しによって表されます。
DoIndependentWork は、作業をし、呼び出し元に返される同期メソッドです。
AccessTheWebAsync は getStringTaskの結果がなくても行うことができる作業を使い果たしました。次 のAccessTheWebAsync はダウンロードする文字列の長さを計算し、返す必要があるがメソッドに文字列が見つかるまでメソッドはその値を計算することはできません。
したがって、AccessTheWebAsync が進行を停止し、AccessTheWebAsyncを呼び出したメソッドにコントロールを開始するために、演算子を使用します。AccessTheWebAsync は呼び出し元に Task(Of Integer) か Task<int> を返します。タスクはダウンロードする文字列の長さの整数の結果が約束を表します。
[!メモ]
GetStringAsyncAccessTheWebAsync がまで待機する前に (つまり完全 getStringTask) の場合、コントロールは AccessTheWebAsyncに残ります。AccessTheWebAsync に中断して返すことのコストが呼び出された非同期プロセス (getStringTask) 既に完了している無駄になると AccessTheWebSync は最終結果を待機する必要がありません。
呼び出し元 (この例のイベント ハンドラー) で、プロセスが繰り返されます。呼び出し元は依存しない、または呼び出し元は AccessTheWebAsync の結果にその結果を待機する直前に待機する可能性がある他の作業を行う場合があります。イベント ハンドラーが期待の式に到達すると、アプリケーションは GetStringAsyncの完了について説明します。イベント ハンドラーは AccessTheWebAsyncを待機しており、AccessTheWebAsync は、GetStringAsyncを待機します。
GetStringAsync は、文字列の結果を完了し、生成します。文字列の結果が意図したとおりの方法で GetStringAsync の呼び出しによって返されません。(メソッドが既に手順 3.のタスクを返したことを忘れないでください) 代わりに、文字列の結果は、メソッドの完了を表すタスク、getStringTaskに格納されます。演算子は、予期 getStringTaskから結果を取得します。代入ステートメントは urlContentsに取得された結果を再配置。
AccessTheWebAsync に文字列の結果がの場合、メソッドは、文字列の長さを計算できます。次 AccessTheWebAsync の作業には、完全であり、待機するイベント ハンドラーが再開できます。トピックの最後に完全な例では、イベント ハンドラーが長さの結果の値を取得し、印刷することを確認できます。
非同期プログラミングの経験がない場合は、同期的および非同期動作の違いを考慮する分にかかってします。同期メソッドは、処理が中断されると作業が完了しても返されます (手順 5)、非同期のメソッドは、タスクの値を返します (手順 3 と 6)非同期のメソッドが最終的に作業を完了すると、タスクが完了とマークされ、結果が存在する場合、タスクに格納されます。
制御フローに関する詳細については、非同期プログラムにおける制御フロー (C# および Visual Basic)を参照してください。
API の単一のメソッド
async のプログラミングをサポートする GetStringAsync などのメソッドを検索またはに疑問場合があります。.NET Framework 4.5 は async を使用し、待機する多数のメンバーも含まれます。Task または Task<TResult>のメンバーの名前と戻り値の型にアタッチされている "Async" サフィックスによってこれらのメンバーを確認できます。たとえば、System.IO.Stream のクラスは、同期メソッド CopyTo、Readと Writeの水平 CopyToAsync、ReadAsyncと WriteAsync のようなメソッドが含まれています。
Windows ランタイム は、async と使用し、Windows ストア の apps を待機できる多くのメソッドがあります。詳細および例のメソッドは Quickstart: 非同期プログラミングの予想の演算子を使用する非同期プログラミング (Windows ストア apps) 、および WhenAny: .NET Framework と Windows ランタイム間のブリッジ (C# および Visual Basic)" "を参照してください。
Threads
単一のメソッドは非ブロッキング操作の変換です。非同期のメソッドの要求の式が必要なタスクの実行中に現在のスレッドをブロックします。代わりに、式の新しい登録は非同期のメソッド呼び出し元に継続としてメソッドの残りの部分を制御します。
async は、キーワードを作成する追加のスレッドを待機します。単一のメソッドは、非同期のメソッドがスレッドを単独で実行しないため、マルチスレッドは必要ではありません。メソッドは、スレッドの現在のコンテキストと同期の使用時にメソッドがアクティブな場合にのみ実行されます。バックグラウンド スレッドに移動して、CPU バインドされている作業に Task.Run を使用できますが、バックグラウンド スレッドが使用できるようになるため、結果を待っているプロセスと助けません。
非同期プログラミングに async ベースの方法はほぼすべてのケースのある方法をお勧めします。特に、この方法は、コードがより簡単です。また、競合状態に保護する必要がないため、I/O バインド操作の BackgroundWorker より優先されます。Task.Runを組み合わせて、非同期のプログラミングは非同期のプログラミングがその処理から移行する際の調整の詳細を比較 Task.Run のコピーへの分離するため、CPU バインド操作の BackgroundWorker より優先されます。
非同期操作は、待ち
メソッドは [Async] または [async] 修飾子を使用して非同期メソッドの実行を指定する場合は、次の 2 種類の機能を有効にします。
マークされた非同期のメソッドは中断ポイントを示すために [Await] か 待機します。 を使用できます。要求の演算子は、予期した非同期処理が完了するまで非同期のメソッドが過去を続行できないようにコンパイラに指示します。指す一方、コントロールは非同期のメソッド呼び出し元に返します。
要求の式の非同期のメソッドの中断がメソッドの終了を構成せず、finally ブロックは実行されません。
マークされた非同期のメソッド自体は、呼び出し元のメソッドによって待機できます。
非同期のメソッドは、通常の演算子の一つ以上の出現が含まれますが、休暇期間は、式はありませんコンパイラ エラーを待機します。中断ポイントを表す場合に非同期のメソッドが使用の演算子を使用するメソッドは同期メソッドと同様に実行されます async 修飾子に関係なく。コンパイラはこのようなメソッドに対して警告が発行されます。
Async、async、Awaitと await は、コンテキスト キーワードです。詳細については、次のトピックを参照:
型およびパラメーターを返します。
.NET Framework プログラミングでは非同期のメソッドは、一般 Task か Task<TResult>を返します。非同期のメソッド内で演算子は、予期の呼び出しから別の非同期のメソッドに返されるタスクに適用されます。
メソッドが TResult型のオペランドを指定する [Return] (Visual Basic) または (返します。、C) ステートメントが含まれている場合 Task<TResult>、戻り値の型を指定します。
メソッドに return ステートメントがなく、オペランドを返さない return ステートメントがない場合、戻り値の型 Task を使用します。
の Task<TResult> か 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 の戻り値の型待機することはできない async のメソッドと無効を返すメソッドの呼び出し元はメソッドがスローする例外をキャッチできません。
非同期のメソッドは Visual Basic または ref の ByRef のパラメーターまたは、C の t3c3bfhx(v=vs.110).md のパラメーターを宣言できませんがメソッドは、このようなパラメーターを持つメソッドを呼び出します。
使用例を含む詳細については、「非同期の戻り値の型 (C# および Visual Basic)」を参照してください。非同期のメソッドの例外をキャッチする方法の詳細については、try-catch (C# リファレンス) か Try...Catch...Finally ステートメント (Visual Basic)を参照してください。
Windows ランタイム のプログラミングの非同期 API にタスクに似た次の戻り値の型の 1 つがです:
IAsyncAction、Taskに対応する
詳細については、" "を参照してください。Quickstart: 非同期プログラミングの予想の演算子を使用する
名前付け規約
規則により、Async または async 修飾子を持つメソッドの名前に "Async" を追加します。
イベント、基本クラス、またはインターフェイスのコントラクトが別の名前を指定する規則を無視できます。たとえば、Button1_Clickなど、共通のイベント ハンドラーで、名前を変更しないでください。
関連トピック
Title |
説明 |
サンプル |
---|---|---|
チュートリアル: Async と Await を使用した Web へのアクセス (C# および Visual Basic) |
非同期 WPF のソリューションに同期 WPF のソリューションを変換する方法を示します。アプリケーションは、一連の Web サイトをダウンロードします。 |
|
前のチュートリアルに Task.WhenAll を追加します。WhenAll の使用は、すべてのダウンロードを同時に開始します。 |
||
複数のタスクを同時に呼び出す方法を示します。 |
||
async のを返すメソッドができるついて説明し、各型が適切な状況についてする型が含まれています。 |
||
トレースの詳細を実行してコントロールのフローの非同期プログラミングの式を待機します。 |
||
独自の非同期のソリューションに次の機能を追加する方法を示します: |
||
実行中にアクティブな非同期操作を再起動するケースを処理する方法を示します。 |
||
WhenAny: .NET Framework と Windows ランタイム間のブリッジ (C# および Visual Basic) |
Windows ランタイム のメソッドの WhenAny を使用できるように .NET Framework のタスクの種類と Windows ランタイム の IAsyncOperations の間のブリッジする方法を示します。 |
|
キャンセル: .NET Framework と Windows ランタイム間のブリッジ (C# および Visual Basic) |
Windows ランタイム のメソッドの CancellationTokenSource を使用できるように .NET Framework のタスクの種類と Windows ランタイム の IAsyncOperations の間のブリッジする方法を示します。 |
|
リストは async を使用する利点を示し、ファイルにアクセスするのに待機します。 |
||
要求のステートメントの制御フローを示す、非同期のメソッド内の [ステップ イン]、[ステップ オーバー] と [ステップ アウト] のコマンドの動作を示します。 |
||
.NET Framework で asynchrony の新しいパターンについて説明します。パターンは Task と Task<TResult> の型に基づいています。 |
||
async を使用して Windows ストア アプリケーションで待機する方法を示します。 |
||
Windows ランタイムで使用した非同期プログラミングの概要を提供します。 |
||
async のプログラミングに関するさまざまなビデオへのリンクを示します。 |
コード例全体
次のコードは、このトピックで説明する Windows Presentation Foundation (WPF) のアプリケーションから MainWindow.xaml.vb または MainWindow.xaml.cs ファイルです。サンプルは、単一の例: "Async を使用した非同期プログラミングの例は、待ち"、からダウンロードできます。
' 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.