非同期呼び出しを行う

同期呼び出しを行う手順は簡単です。クライアントはサーバー オブジェクトのインターフェイス ポインターを取得し、そのポインターを介してメソッドを呼び出します。 非同期呼び出しには呼び出しオブジェクトが含まれるため、さらにいくつかの手順が必要です。

同期インターフェイス上のメソッドごとに、対応する非同期インターフェイスは 2 つのメソッドを実装します。 これらのメソッドは、Begin_プレフィックスをアタッチし、同期メソッドの名前にFinish_します。 たとえば、ISimpleStream という名前のインターフェイスに Read メソッドがある場合、AsyncISimpleStream インターフェイスにはBegin_ReadとFinish_Readメソッドがあります。 非同期呼び出しを開始するために、クライアントは Begin_ メソッドを呼び出します。

非同期呼び出しを開始するには

  1. サーバー オブジェクトに ICallFactory インターフェイスのクエリを実行します。 QueryInterface がE_NOINTERFACEを返す場合、サーバー オブジェクトは非同期呼び出しをサポートしていません。

  2. ICallFactory::CreateCall を呼び出して、目的のインターフェイスに対応する呼び出しオブジェクトを作成し、ICallFactory へのポインターを解放します。

  3. CreateCall の呼び出しから非同期インターフェイスへのポインターを要求しなかった場合は、呼び出しオブジェクトに対して非同期インターフェイスのクエリを実行します。

  4. 適切なBegin_ メソッドを呼び出します。

サーバー オブジェクトが非同期呼び出しを処理するようになりました。クライアントは、呼び出しの結果が必要になるまで、他の作業を自由に実行できます。

呼び出しオブジェクトは、一度に 1 つの非同期呼び出しのみを処理できます。 保留中の非同期呼び出しが完了する前に、同じクライアントまたは 2 番目のクライアントがBegin_ メソッドを呼び出した場合、Begin_ メソッドはRPC_E_CALL_PENDINGを返します。

クライアントが Begin_ メソッドの結果を必要としない場合は、このプロシージャの最後に呼び出しオブジェクトを解放できます。 COM はこの状態を検出し、呼び出しをクリーンアップします。 Finish_ メソッドは呼び出されず、クライアントは out パラメーターまたは戻り値を取得しません。

サーバー オブジェクトは、Begin_ メソッドから戻る準備ができたら、実行されたことを呼び出しオブジェクトに通知します。 クライアントの準備ができたら、呼び出しオブジェクトがシグナル通知されたかどうかを確認します。 その場合、クライアントは非同期呼び出しを完了できます。

クライアントとサーバーの間でこのシグナリングとチェックを行うメカニズムは、呼び出しオブジェクトの ISynchronize インターフェイスです。 通常、呼び出しオブジェクトは、システム提供の同期オブジェクトを集計することによって、このインターフェイスを実装します。 同期オブジェクトは、 ISynchronize::Signal を呼び出して、Begin_ メソッドから戻る直前にサーバーが通知するイベント ハンドルをラップします。

非同期呼び出しを完了するには

  1. ISynchronize インターフェイスの呼び出しオブジェクトに対してクエリを実行します。

  2. ISynchronize::Wait を呼び出します。

  3. Wait がRPC_E_TIMEOUTを返す場合、Begin_ メソッドの処理は完了していません。 クライアントは他の作業を続行し、後でもう一度 Wait を 呼び出すことができます。 Wait がS_OKを返すまで、Finish_ メソッドを呼び出すことはできません。

    Wait がS_OKを返す場合は、Begin_ メソッドが返されます。 適切なFinish_ メソッドを呼び出します。

Finish_ メソッドは、クライアントに out パラメーターを渡します。 Finish_ メソッドの戻り値を含む非同期メソッドの動作は、対応する同期メソッドの動作と正確に一致する必要があります。

クライアントは、Finish_ メソッドが戻るとすぐに呼び出しオブジェクトを解放するか、呼び出しオブジェクトへのポインターを保持して追加の呼び出しを行うことができます。 どちらの場合も、クライアントは、オブジェクトが不要になったときに呼び出しオブジェクトを解放する役割を担います。

呼び出しが進行中でないときに Finish_ メソッドを呼び出すと、メソッドはRPC_E_CALL_COMPLETEを返します。

Note

クライアント オブジェクトとサーバー オブジェクトが同じアパートメント内にある場合、 ICallFactory::CreateCall の呼び出しが成功するとは限りません。 サーバー オブジェクトが特定のインターフェイスでの非同期呼び出しをサポートしていない場合、呼び出しオブジェクトを作成しようとすると失敗し、クライアントは同期インターフェイスを使用する必要があります。

 

非同期呼び出しの取り消し

非同期呼び出し中のクライアント セキュリティ

偽装と非同期呼び出し