COM:他のスレッドから呼び出すとクラッシュします。同じスレッドで実行する方法は?
-
11-07-2019 - |
質問
他のスレッドでイベントを受信するBHO(IEの拡張)を実行しています。他のスレッドからDOMにアクセスすると、IEがクラッシュします。メインのBHOスレッドと同じスレッドからDOMにアクセスして、クラッシュしないようにすることは可能ですか?
これは一般的なCOMマルチスレッドの問題のように思えますが、あまり理解していません。
解決
CoMarshalInterface または CoMarshalInterThreadInterfaceInStream
これらは、スレッドセーフなSTA COMオブジェクトへのラップされたインターフェイスを提供します。
他のヒント
IE拡張機能についてはあまり知りませんが、COMランタイムシステムが最初に呼び出したスレッドと同じスレッドで実行されるようにするには、一部のCOMオブジェクトをシングルスレッドアパートメントとしてマークする必要があるようです。他のオブジェクトを変更できない場合、おそらく同じ効果を達成するために、STAとマークされた別のCOMオブジェクトを介して呼び出しをDOMにルーティングできます。これが役立つことを願っています... COMマルチスレッドについては少し知っていますが、IE拡張についてはあまり知りません。
ああ、楽しい楽しい楽しいCOMによるマルチスレッド。
Geraldの答えは、あるスレッドから別のスレッドにインターフェイスポインターを1回だけ転送する場合に適切に見えます。マルチスレッドシステムを使用している場合、GIT(グローバルインターフェイステーブル)がこの種のことの大きな助けになることがわかりました。使用しているスレッドに適切にマーシャリングされたインターフェイスポインターを取得します。 (問題のオブジェクトを最初にGITに登録し、完了またはオブジェクトが終了したら後で登録を解除する必要があります)
しかし注意してください。パフォーマンスは深刻な問題になる可能性があります。
BHOについて学習するために遊んでいる場合は、STAを使用して:: SetSite()実装オブジェクトをシングルスレッドのように動作させることができます(これにより、他のスレッドがBHOのポインターを引き出すことができます@JasonSが言及しているGlobalInterfaceTableの。
製品の一部であることが予想される何かをしている場合は、可能な限りMTAを使用し、並行性とスレッドセーフの問題を自分で処理することを慎重に再検討することを強くお勧めします。この場合、BHO COMオブジェクトと相互運用するスレッド自体がCOM用に初期化されていることのみを確認する必要があります。
たとえば、ウェブサイトの着信/発信データを監視する場合(危険または機密)-Yahooを次のように使用するため、これらすべてのスレッドをSTAオブジェクトのスロートに強制することは望ましくありません。たとえば、30を超えるリクエストが起動し、BHOがIEのロックを開始します。