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