【问题标题】:Why is Thread.Join not letting through COM messages?为什么 Thread.Join 不让 COM 消息通过?
【发布时间】:2010-11-21 16:54:39
【问题描述】:

我正在运行一些执行以下操作的多线程代码。

  1. 在 STA 线程上,我创建了一个 'worker' 线程,然后运行它。
  2. 然后 STA 线程等待工作线程 线程退出。
  3. 工作线程调用 STA COM 代理上的方法 STA 线程上的对象,然后退出。

在第 2 步中,我使用Thread.Join() 等待工作线程退出。

Thread.Join() 的文档指出它阻塞调用线程直到线程终止,同时继续执行标准 COM 和 SendMessage 泵送

但是,工作线程会在 COM 调用上“永远”阻塞。 STA 线程从不为 COM 调用提供服务,而在工作线程上调用 Thread.Join() 时会被阻塞。

我希望 STA 线程能够在被 Thread.Join 阻塞时为 COM 调用提供服务。

谁能解释这里可能发生的事情?


这是调用 Thread.Join 的本机调用堆栈(在本机代码调试模式下运行 VS,所以差异可能是由于不使用 WinDbg?):
ntdll.dll!_KiFastSystemCallRet@0()  
ntdll.dll!_ZwWaitForMultipleObjects@20()  + 0xc bytes
kernel32.dll!_WaitForMultipleObjectsEx@20()  - 0x51 bytes   
user32.dll!_RealMsgWaitForMultipleObjectsEx@20()  + 0xd7 bytes  
ole32.dll!CCliModalLoop::BlockFn()  + 0x8c bytes    
ole32.dll!_CoWaitForMultipleHandles@20()  - 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

【问题讨论】:

  • 我觉得这很有趣,也很吓人。您能否附加一个本机调试器(带有完整符号 - 如果您还没有“Microsoft 符号服务器”,请使用谷歌)并查看 Thread.Join STA 的调用堆栈是否与参考文章中显示的内容匹配?

标签: c# multithreading com clr sta


【解决方案1】:

您的工作线程是否在 MTA 公寓中运行?如果当前单元是 MTA,则 Thread.Join 将不会执行抽水。在这种情况下,MSDN 上的文档具有误导性,因为不注入 MTA 是标准的。

这是一篇关于这个主题的文章

EDIT 重新阅读问题,发现阻塞线程是一个 STA 线程。将答案保留为 CW,以防它帮助人们以所描述的方式解决问题

【讨论】:

  • Thread.Join 在 STA 线程中被调用。工人是我认为的 MTA - 只是默认值。你的 cmets 还适用吗?
  • 答案赞成与 Chris Brumme 文章的间接链接,但这可能会有所帮助...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-12
  • 1970-01-01
  • 2017-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多