2009-08-21 6 views
2

私は次のことをするいくつかのマルチスレッドコードを実行しています。Thread.JoinがCOMメッセージを通過させないのはなぜですか?

  1. STAスレッドでは、 ワーカースレッドを作成して実行します。
  2. STAスレッドは、ワーカー スレッドが終了するのを待ちます。
  3. ワーカースレッドは、STAスレッド上のSTA COM オブジェクトへのプロキシのメソッドを呼び出して終了します。

手順2では、私はThread.Join()を使用して、ワーカースレッドが終了するまで待っています。スレッドが終了するまで、標準のCOMとのSendMessageポンピングを実行するために継続しながら

Thread.Join()のドキュメントは、それブロック呼び出し元のスレッドと述べています。

しかし、何が起こるかは、ワーカースレッドがCOM呼び出しで「永遠に」ブロックすることです。 STAスレッドはCOM呼び出しを処理しませんが、ワーカースレッドのThread.Join()を呼び出すとブロックされます。

私はSTAスレッドがThread.Joinでブロックされている間にCOM呼び出しを処理できると予想しました。

ここで何が起こっているのかも説明できますか?


がここThread.Joinへの呼び出しをネイティブコールスタックです(違いはWinDbgのを使用していないが原因である可能性がありので、ネイティブコードのデバッグモードでVSを走った?):ここで
[email protected]() 
[email protected]() + 0xc bytes 
[email protected]() - 0x51 bytes 
[email protected]() + 0xd7 bytes 
ole32.dll!CCliModalLoop::BlockFn() + 0x8c bytes  
[email protected]() - 0x382a bytes  
mscorwks.dll!NT5WaitRoutine() + 0x39 bytes 
mscorwks.dll!MsgWaitHelper() + 0x97 bytes 
mscorwks.dll!Thread::DoAppropriateAptStateWait() + 0x51ae9 bytes 
mscorwks.dll!Thread::DoAppropriateWaitWorker() + 0x104 bytes 
mscorwks.dll!Thread::DoAppropriateWait() + 0x40 bytes 
mscorwks.dll!Thread::JoinEx() + 0x77 bytes 
mscorwks.dll!ThreadNative::DoJoin() + 0xa6 bytes 
mscorwks.dll!ThreadNative::Join() + 0xa8 bytes 

を示すコールスタックでありますarticle、Thread.Joinを呼び出すSTAスレッドの場合: 最後の呼び出しで表示されているものとは異なるように見えます。ここで

ntdll!NtWaitForMultipleObjects+0xa 
KERNEL32!WaitForMultipleObjectsEx+0x10b 
USER32!RealMsgWaitForMultipleObjectsEx+0x129 
USER32!MsgWaitForMultipleObjectsEx+0x46 
ole32!CCliModalLoop::BlockFn+0xbb 
ole32!CoWaitForMultipleHandles+0x145 
mscorwks!NT5WaitRoutine+0x77 
mscorwks!MsgWaitHelper+0xed 
mscorwks!Thread::DoAppropriateAptStateWait+0x67 
mscorwks!Thread::DoAppropriateWaitWorker+0x195 
mscorwks!Thread::DoAppropriateWait+0x5c 
mscorwks!Thread::JoinEx+0xa5 
mscorwks!ThreadNative::DoJoin+0xda 
mscorwks!ThreadNative::Join+0xfa 

は、MTAスレッドの記事のコールスタックです:

ntdll!NtWaitForMultipleObjects+0xa 
KERNEL32!WaitForMultipleObjectsEx+0x10b 
mscorwks!WaitForMultipleObjectsEx_SO_TOLERANT+0xc1 
mscorwks!Thread::DoAppropriateAptStateWait+0x41 
mscorwks!Thread::DoAppropriateWaitWorker+0x195 
mscorwks!Thread::DoAppropriateWait+0x5c 
mscorwks!Thread::JoinEx+0xa5 
mscorwks!ThreadNative::DoJoin+0xda 
mscorwks!ThreadNative::Join+0xfa 
+1

これは非常に興味深く、恐ろしいと思います。ネイティブのデバッガを添付することができますか?(完全な記号 - 「Microsoft symbol server」がない場合はGoogleを参照してください)、Thread.Join STAのコールスタックが参照されている記事と一致するかどうかを確認してください。 –

+0

良いアイデア。私はそれを試みます。 – mackenir

答えて

1

はMTAのアパートで動作し、あなたのワーカースレッドですか?現在のマンションがMTAの場合、Thread.Joinはポンピングを実行しません。 MSDNのドキュメントは、MTAをポンピングしないことが標準であるため、この場合誤解を招きます。ここで

EDIT再読み込み質問ビットの対象品であるとブロッキングスレッドがSTAスレッドであることがわかりました。人々が問題にぶつかるのを助ける場合のためのCWとしての回答を残す

+0

STAスレッドでThread.Joinが呼び出されています。作業者は私が思うMTAです。デフォルトのものは何でも構いません。あなたのコメントはまだ適用されますか? – mackenir

+0

Dang。:) ________ – mackenir

+1

それにもかかわらず助けるかもしれないクリスBrummeの記事への間接的なリンクのためのupvoted ... – mackenir

関連する問題