COMランタイムは、STA内のCOMオブジェクトのメソッドへの呼び出しのディスパッチを処理します。これはWindowsメッセージのディスパッチに使用されるのと同じOSメカニズムに基づいていることは間違いありませんが、これを実現することを心配する必要はありません。 COMは、内部でこれを行います。
心配する必要があるのは、COMオブジェクトがどのSTAに存在するかです。WCFサービスからCOM相互運用機能を使用してアパートメントスレッドのCOMオブジェクトをインスタンス化する場合は、注意が必要です。
これを行うスレッドがSTAスレッドでない場合、すべてのインプロセスCOMオブジェクトは、IISワーカープロセスの既定のホストSTAに存在します。これが発生することは望ましくありません。すべてのサービス操作のすべてのCOMオブジェクトは、この同じSTAに配置されます。手がかりは名前にあります-すべてのオブジェクトに対して1つのスレッドがあります-そしてそれらのメソッドへのすべての呼び出しは、アパート内の唯一のスレッドがそれらを実行するのを待ってシリアル化されます。サービスは、複数の同時クライアントを処理するように拡張されません。
特定のWCF要求を処理するためにインスタンス化するCOMオブジェクトが、他の要求用に作成されたオブジェクトとは別の独自のSTAにあることを確認する必要があります。これを行うには、大きく2つの方法があります。
- 独自のスレッドを起動し、開始する前に指定
ApartmentState.STA
しSetApartmentState()
て、特定の要求に対してCOMオブジェクトをインスタンス化します。これは、 Kevの回答のリンクでScott Seelyによって詳述されたアプローチです。彼は、各サービス操作呼び出しが新しいSTAで初期化されたスレッドで呼び出されることを保証します。これらの方針に沿った、より難しいがよりスケーラブルなソリューションは、再利用可能なSTAで初期化されたスレッドのプールを実装することです。
- COMオブジェクトをCOM+アプリケーションでホストして、別のDllHostプロセスに存在するようにします。ここで、COM +は(と呼ばれる抽象化を通じて)
Activity
さまざまな要求のオブジェクトをさまざまなSTAに配置します。
コールバックについて言及するとき、あなたが何を意味するのか正確にはわかりません。おそらく、COMオブジェクトのメソッドの1つへの引数としてCOMオブジェクトに渡された参照を介して、マネージコードに実装されたCOMインターフェイスでCOMメソッドが呼び出されることを意味します。そうであれば、これは正常に機能するはずです。しかし、おそらくあなたは何か他のものを意味します。その場合、おそらくあなたは明確にするために質問を修正することができます。