2

.NET アプリケーションのスレッドで作成および実行している COM オブジェクトがいくつかあります。スレッドはシングル スレッド アパートメントとしてマークされており、すべてが機能しているようです。私の理解では、これらのスレッドがメイン スレッドから COM オブジェクトにアクセスしようとすると、それらのオブジェクトは .NET で自動的にマーシャリングされ、シリアル化されます。少しゆっくり。

私の質問は、問題なく動作しているように見えますが、作成中の STA スレッドでメッセージ ループをポンピングしていないということです。メッセージ ループを回避したいのは、それが引き起こす余分な複雑さ (および効率の低下の可能性) のためです。

なぜメッセージ ループが必要なのかについてのアドバイスをたくさん読みました (主に非常に役立つ Hans Passant から)。私の理解では、メッセージ ループはスレッド A に、他のスレッド B がその COM オブジェクトを要求できる場所を提供します。スレッド A に住んでいると、マーシャリングして遊ぶことができます。それが正しければ、他のスレッドがスレッド A の COM オブジェクトから何も要求しない限り、スレッド A はメッセージ ループをポンピングしないことで安全でしょうか? または、メッセージ ループが発生する可能性がある他のケースはありますか?

ここで火遊びですか?また、火遊びをしているのか、そうでないのかと尋ねることはありますか?

4

2 に答える 2

4

STAコントラクトでは、メッセージループをポンピングする必要があります。しかし、はい、ポンプを使わずに逃げることは可能です。うまくいかない可能性のある2つの主要なことがあります。

  • 別のSTAスレッドまたはMTAのスレッドを含む、別のアパートメントからのインターフェイスメソッドで行われた呼び出しは完了しません。これはプログラムのデッドロックのように見えます。呼び出しが戻ることはありません。自分の呼び出しを非常にうまく制御できますが、COMコンポーネントが何をしているのかわからないことに注意してください。スレッド自体を開始する可能性があります。これは、Debug + Windows+Threadsを使用したデバッガーで確認できます。デバッガーをアンマネージモードで実行していること、および表示されるすべてのスレッドを考慮できることを確認してください。ところで、特に簡単ではありません。

  • 多くのアパートのスレッド化されたCOMコンポーネントは、独自のニーズを処理するメッセージループを持つことを期待しています。タイマーとしては無害なものである可能性があり、ループがない場合はカチカチ音をたてません。または、内部でマーシャリングを行う場合があります。Spy ++を使用して、新しいSTAスレッドが所有する非表示のウィンドウがあるかどうかを確認します。表示された場合は問題の兆候を確認してください。診断は、誤動作しているコンポーネントです。イベントを発生させないことはよくある事故です。

サーバーの内部について十分に理解していない場合、壁に釘付けになることは何もありません。必ずそれをテストしてください。

于 2012-05-19T00:43:52.393 に答える
1

COM 呼び出しは、メッセージ ループなしでマーシャリングできます。

STA スレッドが何かを待機している場合、ほとんどの場合、保留中の COM 呼び出しが自動的に処理されます。

Thread.Joinのドキュメントには、Blocks the calling thread [...] while continuing to perform standard COM and SendMessage pumping.

スレッドが IO を待機している場合など、あなたに代わって呼び出される他の多くの関数 (CoWaitForMultipleHandles など) でも同じことが起こります。

于 2012-05-18T19:25:46.540 に答える