COM オブジェクトは非同期呼び出しをサポートできます。 クライアントが非同期呼び出しを行うと、コントロールはすぐにクライアントに戻ります。 サーバーが呼び出しを処理している間、クライアントは他の作業を自由に実行できます。 クライアントが呼び出しの結果なしで続行できなくなった場合は、その時点で呼び出しの結果を取得できます。
たとえば、大規模または複雑なレコードセットの要求には時間がかかる場合があります。 クライアントは、非同期呼び出しによってレコードセットを要求し、その他の処理を実行できます。 レコードセットが使用可能な場合、クライアントはブロックすることなくすばやくレコードセットを取得できます。
クライアントは、サーバー オブジェクトに対して直接非同期呼び出しを行いません。 代わりに、サーバー オブジェクトに同期インターフェイスの非同期バージョンを実装する呼び出しオブジェクトを取得します。 呼び出しオブジェクトの非同期インターフェイスには、AsyncInterfaceNameという形式の名前があります。 たとえば、サーバー オブジェクトが IMyInterface という名前の同期インターフェイスを実装する場合、AsyncIMyInterface という名前の非同期インターフェイスを実装する呼び出しオブジェクトがあります。
手記
IDispatch、または IDispatchを継承するインターフェースでは、非同期サポートは利用できません。
非同期呼び出しをサポートするサーバー オブジェクトは、ICallFactory インターフェイスを実装します。 このインターフェイスは、CreateCall1 つのメソッドを公開します。これにより、指定した呼び出しオブジェクトのインスタンスが作成されます。 クライアントは、ICallFactory を照会して、オブジェクトが非同期呼び出しをサポートしているかどうかを判断できます。
同期インターフェイスの各メソッドに対して、対応する非同期インターフェイスは 2 つのメソッドを実装します。 これらのメソッドは、Begin_プレフィックスとFinish_を同期メソッドの名前にアタッチします。 たとえば、ISimpleStream という名前のインターフェイスに Read メソッドがある場合、AsyncISimpleStream インターフェイスにはBegin_ReadとFinish_Read メソッドがあります。 非同期呼び出しを開始するために、クライアントは Begin_ メソッドを呼び出します。
サーバー オブジェクトを実装するときに、オブジェクトが実装するすべてのインターフェイスに対して呼び出しオブジェクトを指定する必要はありません。 サーバー オブジェクトが ICallFactory インターフェイスを実装し、標準のマーシャリングを使用する場合、マーシャリングされたクライアントは、サーバー側に呼び出しオブジェクトがない場合でも、常にプロキシ呼び出しオブジェクトを取得できます。 このプロキシは、Begin_ メソッドを同期呼び出しとしてマーシャリングし、サーバーは呼び出しを同期的に処理し、クライアントは Finish_ メソッドを呼び出すことによって out パラメーターを取得できます。
逆に、クライアントがサーバー側に呼び出しオブジェクトがあるインターフェイスでマーシャリングされた同期呼び出しを行うと、サーバーは常に非同期的に呼び出しを処理します。 クライアントは同期メソッドから受け取ったのと同じ out パラメーターと同じ戻り値を受け取るため、この動作はクライアントでは明らかになりません。
どちらの場合も、クライアントとサーバーの間の相互作用は、呼び出しが同期的であるかのようにマーシャリングされます。同期プロキシと非同期プロキシの出力は、対応するスタブの出力と同様に区別できません。 この動作により、クライアントとサーバーの両方のプログラミング モデルが大幅に簡略化されます。 サーバー オブジェクトが ICallFactory実装している場合、マーシャリングされたクライアントは、使用できない可能性がある呼び出しオブジェクトを作成する必要はありません。クライアントに対して、呼び出しオブジェクトは常に使用できます。
クライアントとサーバーが同じアパートメント内にある場合、サーバー オブジェクトは、クライアントが行う呼び出しを処理します。 呼び出しオブジェクトが使用できない場合、クライアントは明示的に同期インターフェイスを取得し、同期呼び出しを行う必要があります。
詳細については、次のトピックを参照してください。
- 非同期呼び出しを行う
- 非同期呼び出しを取り消す
- メソッド呼び出しの取り消し
- 呼び出し同期