C#マルチスレッド環境でレガシーCOMコンポーネントを使用する
-
06-07-2019 - |
質問
レガシーCOMコンポーネントがあり、その使命は、COMをラップして同時非ブロッキング呼び出しを有効にするWebサービスを作成することです。
まず、COMオブジェクト自体はステートレスなので、[ThreadStatic]属性を使用して、各スレッドがCOMオブジェクトの独自のインスタンスを持ち、lock {}ステートメントの使用を防ぎ、実際の同時処理を可能にすることにしました、しかし、すべての呼び出しはまだ同期的に進行しているようです。
COMコンポーネントからfor {}ループと同期するメソッドを実行するテストコードを作成し、COMオブジェクトの別のインスタンスにまったく同じことを行う2番目のスレッドを追加しました。スレッド数に関係なく、常にY回のタイムスパンを消費します。静的ロックまたは何かがあるようです...
それにもかかわらず、個別のプロセスが実際に各呼び出しを同時に処理できます。別々のスレッドが同じ動作をするのを防ぐものは何ですか?
COMコンポーネントへの実際の同時呼び出しを有効にするにはどうすればよいですか?
解決
COMはスレッド対応であり、コクラスによって要求されたスレッドモデルを尊重します。レジストリのThreadingModel値を使用して、スレッド要件を公開します。 「アパート」に設定されている場合(または欠落している)、COMは、QIするインターフェイスのプロキシを返すことにより、すべてのメソッド呼び出しが単一のスレッドアパートメントから行われるようにします。プロキシは、呼び出しが正しいスレッドにマーシャリングされるようにします。
STAスレッドでコクラスを作成したときに取得したインターフェイスポインターをチートして使用し、マーシャリングせずに呼び出しを行うことができます。コクラスがすでにマルチスレッドに対応していないと言っていることを考えると、これは正しく動作する可能性が非常に低いです。内部状態がランダムに破損するだけです。