3

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

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

在第 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 

这是文章中显示的调用堆栈,用于调用 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
4

1 回答 1

1

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

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

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

于 2009-08-21T15:19:10.907 回答