0

お客様の環境で非常に奇妙な問題が発生しています。3 つまたは 4 つのインプロセス COM オブジェクト (dll) を呼び出す exe があります。これらの dll は、(COM イベントを介して) 相互に呼び出し、メインの exe も呼び出します。

これは長い間 (5 年?) 正常に機能し、何千ものマシンで引き続き正常に機能しますが、1 人の顧客 (Windows 2008 R2) の場合、システム全体が混乱します。メインの exe はプレーンなバニラ アパートメント スレッド COM オブジェクトを作成します (noカスタム マーシャリング) CoCreateInstance を使用して、そのメソッドの呼び出しを開始します。

数十回または数百回の呼び出しではすべてが正常に機能しますが、実際には予想外のことが起こります。つまり、インプロセス COM オブジェクト (実際には COM によって返されるプロキシ) の 1 つへの呼び出しが、COM によって作成された別のスレッドにマーシャリングされます。そのメソッドはメインの exe にコールバックしますが、コールは別のスレッドにマーシャリングされます。そして、そのスレッドのコードがコントロールへのアクセスを開始すると、本当に悪いことが起こり始めます。メイン スレッドがブロックされ、セカンダリ スレッドからメイン スレッドで作成されたコントロールへのアクセスもブロックされます (SentMessage、GetPropW など)。

誰もこれを見たことがありますか?

この動作を無効にするか、COM マーシャリングを完全に取り除く方法はありますか (この場合、アプリによって作成されたスレッドがないため、これは役に立ちません)。

CoCreateInstance() を独自の関数に置き換えました。この関数は、クラス GUID を指定して、実行可能パスを計算し、それをロードし、DllgetClassObject を呼び出し、次に IClassFactory::CreateObject を呼び出します。これで問題なく動作し、すべてのオブジェクトがメイン スレッドで実行されるようになりました。しかし、アウト オブ プロセス オブジェクト (私のバージョンの CoCreateInstance は触れていません) も同様のエラーで失敗し始めます。Outlook.Application オブジェクトのインスタンスを作成してから、新しい MailItem オブジェクトを作成します。そのオブジェクトの任意のプロパティにアクセスする と、'The application called an interface that was marshalled for a different thread' が返されるようになりました。そうではありませんでした!オブジェクトの作成時にスレッド ID をログに記録しました。すべての呼び出しはメイン スレッド上にあります。

ヘルプ!どうすればこの狂気を止めることができますか?

ありがとうございました!

4

0 に答える 0