完全な同期

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

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

同期呼び出し

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

非同期通知

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

Note

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

 

入力同期呼び出し

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

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

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