非同期プログラミング モデル (APM)

IAsyncResult デザイン パターンを使用する非同期操作は BeginOperationNameEndOperationName という名前の、各 OperationName 非同期操作を開始および終了する 2 種類のメソッドとして実装されます。 たとえば、 FileStream クラスは、 BeginRead および EndRead メソッドを提供して、非同期的にファイルからバイトを読み取ります。 これらのメソッドは非同期バージョンの Read メソッドを実装します。

注意

.NET Framework 4 以降では、タスク並列ライブラリによって非同期/並列プログラミングの新しいモデルが提供されます。 詳細については、「 タスク並列ライブラリ (TPL) 」および「 タスク ベースの非同期パターン (TAP)」を参照してください。

BeginOperationName を呼び出した後、アプリケーションは別のスレッドで非同期操作が行われている間も、スレッドの呼び出しに関する命令の実行を続行できます。 BeginOperationName の呼び出しごとに、アプリケーションでは EndOperationName も呼び出して、操作の結果を取得する必要があります。

非同期操作の開始

BeginOperationName メソッドは非同期操作 OperationName を開始し、IAsyncResult インターフェイスを実装するオブジェクトを返します。 IAsyncResult オブジェクトは非同期操作に関する情報を格納します。 非同期操作に関する情報を次の表に示します。

メンバー 説明
AsyncState 非同期操作についての情報を格納するオプションのアプリケーション固有オブジェクト。
AsyncWaitHandle WaitHandle 。非同期操作が完了するまでアプリケーションの実行をブロックするために使用できます。
CompletedSynchronously 非同期操作が別の ThreadPool スレッドで完了する代わりに、BeginOperationName の呼び出しに使用されたスレッドで完了したかどうかを示す値。
IsCompleted 非同期操作が完了したかどうかを示す値。

BeginOperationName メソッドは、同期バージョンのメソッドのシグネチャで宣言された、値渡しまたは参照渡しのパラメーターを受け取ります。 どの out パラメーターも、BeginOperationName メソッド シグネチャの一部ではありません。 BeginOperationName メソッド シグネチャには、2 種類の追加のパラメーターが含まれます。 1 つ目のパラメーターは、非同期操作が完了したときに呼び出されるメソッドを参照する AsyncCallback デリゲートを定義します。 操作完了時にメソッドを呼び出さない場合、呼び出し元は null (Visual Basic ではNothing ) を指定できます。 2 つ目の追加のパラメーターは、ユーザー定義オブジェクトです。 このオブジェクトは、アプリケーション固有の状態情報を、非同期操作が完了したときに呼び出されるメソッドに渡すために使用できます。 BeginOperationName メソッドが、ファイルから読み取ったバイトを格納するバイト配列など操作固有の追加のパラメーターを受け取る場合は、AsyncCallback とアプリケーション状態オブジェクトが BeginOperationName メソッド シグネチャの最後のパラメーターになります。

BeginOperationName は、瞬時にコントロールを呼び出し元スレッドに返します。 BeginOperationName メソッドが例外をスローする場合は、非同期操作が開始される前に例外がスローされます。 BeginOperationName メソッドが例外をスローする場合、コールバック メソッドは呼び出されません。

非同期操作の終了

EndOperationName メソッドは非同期操作の OperationName を終了します。 EndOperationName メソッドの戻り値は、このメソッドの対応する同期操作によって返される型と同じ型であり、非同期操作に固有です。 たとえば、 EndRead メソッドは FileStream から読み取ったバイト数を返し、 EndGetHostByName メソッドはホスト コンピューターに関する情報を含む IPHostEntry オブジェクトを返します。 EndOperationName メソッドは、メソッドの同期バージョンのシグネチャで宣言された out パラメーターや ref パラメーターをすべて受け取ります。 EndOperationName メソッドには、同期メソッドからのパラメーターに加えて IAsyncResult パラメーターが含まれています。 呼び出し元は、対応する呼び出しから返されたインスタンスを BeginOperationName に渡す必要があります。

EndOperationName が呼び出されるときに IAsyncResult オブジェクトによって表される非同期操作が完了していない場合、EndOperationName は非同期操作が完了するまで、呼び出し元スレッドをブロックします。 非同期操作によってスローされた例外は、EndOperationName メソッドからスローされます。 同じ IAsyncResult を使用して EndOperationName メソッドを複数回呼び出す場合の効果は定義されません。 同様に、関連する Begin メソッドによって返されたのではない IAsyncResult を使用した EndOperationName メソッドの呼び出しも定義されません。

注意

どちらの未定義シナリオの場合でも、実装者は InvalidOperationExceptionのスローを検討する必要があります。

注意

このデザイン パターンの実装者は IsCompleted を true に設定し、非同期コールバック メソッドを呼び出して (指定されている場合)、 AsyncWaitHandleをシグナリングすることで、非同期操作の完了を呼び出し元に通知する必要があります。

アプリケーション開発者には、非同期操作の結果にアクセスするための、デザイン上の選択肢がいくつかあります。 どの選択が適切になるかは、アプリケーションが操作の完了前に実行できる命令を持っているかどうかによって変わります。 非同期操作の結果を受け取るまで、アプリケーションが別の作業を実行できない場合は、結果が使用可能になるまで、そのアプリケーションをブロックする必要があります。 非同期操作が完了するまでブロックするには、次に示す方法の 1 つを使用します。

非同期操作が完了するまでアプリケーションをブロックする必要がない場合は、次のいずれかの方法を使用します。

関連項目