通話の同期

COM アプリケーションは、COM またはオペレーティング システムからの 1 つ以上の呼び出しの処理中に、ユーザー入力を正しく処理できる必要があります。 COM では、シングル スレッド アパートメントに対してのみ呼び出し同期が提供されます。 マルチスレッド アパートメント (フリー スレッド スレッドを含む) は、(同じスレッドで) 呼び出しを行っている間は呼び出しを受け取りません。 マルチスレッド アパートメントでは、入力同期呼び出しを行うことはできません。 非同期呼び出しは、マルチスレッド アパートメントの同期呼び出しに変換されます。 マルチスレッド アパートメント内のスレッドに対してメッセージ フィルターは呼び出されません。 スレッドの問題の詳細については、「 プロセス、スレッド、およびアパートメント」を参照してください。

プロセス間の COM 呼び出しは、次の 3 つのカテゴリに分類されます。

同期呼び出し

COM 内で行われる通信のほとんどは同期です。 同期呼び出しを行うとき、呼び出し元は応答を待機してから続行し、待機中に受信メッセージを受信できます。 COM は、応答を待機し、制御された方法で他のメッセージを受信およびディスパッチするためのモーダル ループを入力します。

非同期通知

非同期通知を送信する場合、呼び出し元は応答を待機しません。 COM では 、PostMessage または高レベルのイベントを使用して、プラットフォームに応じて非同期通知を送信します。 COM では、 IAdviseSink の 5 つの非同期メソッドが定義されています。

注意

COM が非同期呼び出しを処理している間は、同期呼び出しを行うことはできません。 たとえば、コンテナー アプリケーションの OnDataChange の実装には、 IPersistStorage::Save の呼び出しを含めることはできません。 これらの呼び出しは、COM でサポートされている唯一の非同期呼び出しです。 現時点では非同期のカスタム インターフェイスを作成する方法はありません。

 

入力同期呼び出し

入力同期呼び出しを行うときは、呼び出されたオブジェクトが制御を生成する前に呼び出しを完了する必要があります。 これにより、フォーカス管理が正しく機能し、ユーザーが入力したデータが適切に処理されます。 これらの呼び出しは、モーダル ループを入力せずに SendMessage 関数を介して COM によって行われます。 入力同期呼び出しの処理中に、呼び出されるオブジェクトは、制御を生成する可能性のある関数またはメソッド (同期メソッドを含む) を呼び出してはなりません。 次のメソッドは入力同期されます

非同期メッセージ処理によって発生する可能性のある問題を最小限に抑えるために、COM メソッド呼び出しの大部分は同期です。 同期通信では、受信メッセージをディスパッチして処理する特別なコードは必要ありません。 アプリケーションが同期メソッド呼び出しを行うと、COM は、必要な応答を処理し、受信メッセージを処理できるアプリケーションにディスパッチするモーダル待機ループを入力します。

COM は、 論理スレッド ID と呼ばれる識別子を割り当てることで、メソッド呼び出しを管理します。 ユーザーがメニュー コマンドを選択したとき、またはアプリケーションが新しい COM 操作を開始すると、新しいコマンドが割り当てられます。 最初の COM 呼び出しに関連する後続の呼び出しには、最初の呼び出しと同じ論理スレッド ID が割り当てられます。