非同期呼び出しの作成と処理

COM オブジェクトは、非同期呼び出しをサポートできます。 クライアントが非同期呼び出しを行うと、制御はすぐにクライアントに戻ります。 サーバーが呼び出しを処理している間、クライアントは他の作業を自由に行うことができます。 クライアントが呼び出しの結果なしで続行できなくなった場合は、その時点での呼び出しの結果を取得できます。

たとえば、大規模または複雑なレコードセットの要求には時間がかかる場合があります。 クライアントは、非同期呼び出しによってレコードセットを要求してから、他の作業を行うことができます。 レコードセットが使用可能な場合、クライアントはブロックすることなくすばやくレコードセットを取得できます。

クライアントは、サーバー オブジェクトで直接非同期呼び出しを行いません。 代わりに、サーバー オブジェクトに同期インターフェイスの非同期バージョンを実装する呼び出しオブジェクトを取得します。 呼び出しオブジェクトの非同期インターフェイスには、AsyncInterfaceName という形式の名前があります。 たとえば、サーバー オブジェクトが IMyInterface という名前の同期インターフェイスを実装する場合、AsyncIMyInterface という名前の非同期インターフェイスを実装する呼び出しオブジェクトがあります。

Note

非同期サポートは、 IDispatch または IDispatch を継承するインターフェイスでは使用できません。

 

非同期呼び出しをサポートするサーバー オブジェクトは 、ICallFactory インターフェイスを 実装します。 このインターフェイスは、指定された呼び出しオブジェクトのインスタンスを作成する単一のメソッド CreateCall を公開します。 クライアントは ICallFactory を 照会して、オブジェクトが非同期呼び出しをサポートしているかどうかを判断できます。

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

サーバー オブジェクトを実装するときに、オブジェクトが実装するすべてのインターフェイスに対して呼び出しオブジェクトを指定する必要はありません。 サーバー オブジェクトが ICallFactory インターフェイスを実装し、標準のマーシャリングを使用する場合、マーシャリングされたクライアントは、サーバー側に呼び出しオブジェクトがない場合でも、常にプロキシ呼び出しオブジェクトを取得できます。 このプロキシは、Begin_ メソッドを同期呼び出しとしてマーシャリングし、サーバーは呼び出しを同期的に処理し、クライアントは Finish_ メソッドを呼び出すことによって out パラメーターを取得できます。

逆に、クライアントが、サーバー側に呼び出しオブジェクトがあるインターフェイスでマーシャリングされた同期呼び出しを行う場合、サーバーは常に非同期的に呼び出しを処理します。 クライアントは同期メソッドから受け取ったのと同じ out パラメーターと同じ戻り値を受け取るため、この動作はクライアントには明らかではありません。

どちらの場合も、クライアントとサーバーの間の相互作用は、呼び出しが同期的であるかのようにマーシャリングされます。同期プロキシと非同期プロキシの出力は、対応するスタブの出力と同様に区別できません。 この動作により、クライアントとサーバーの両方のプログラミング モデルが大幅に簡略化されます。 サーバー オブジェクトが ICallFactory を実装している場合、マーシャリングされたクライアントは、使用できない可能性がある呼び出しオブジェクトを作成する必要はありません。クライアントでは、呼び出しオブジェクトは常に使用できます。

クライアントとサーバーが同じアパートメント内にある場合、サーバー オブジェクトは、クライアントが行う呼び出しを処理します。 呼び出しオブジェクトが使用できない場合、クライアントは明示的に同期インターフェイスを取得し、同期呼び出しを行う必要があります。

詳細については、次のトピックを参照してください。