Why is Thread.Join not skipping COM messages?

I am running some multi-threaded code that does the following.

  • In the STA thread, I create a "worker" thread and start it.
  • The STA thread then waits for the worker thread to exit.
  • The worker thread calls a method on the proxy for the STA COM object on the STA thread, and then exits.

In step 2, I use Thread.Join()

to wait for a worker thread to exit.

The documentation for it Thread.Join()

states that it blocks the calling thread until the thread finishes, continuing to do standard COM forwarding and SendMessage .

However, what happens is that the worker thread blocks "forever" on the COM call. An STA thread never serves a COM call, whereas it blocks when Thread.Join () is called on a worker thread.

I expected the STA thread to be able to service COM calls when Thread.Join is blocked.

Can anyone explain what might be going on here?


Here is the native callstack for calling Thread.Join (VS started in native debug mode, so the differences might be caused by not using 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 

      

Here is the call stack shown in the article for STA threads that call Thread.Join: It looks like it deviates from what I see on the last call.

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

      

Here's a column article for the MTA thread:

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

      

+2


source to share


1 answer


Is your workflow running in the MTA apartment? A Thread.Join will not do the swap if the current flat is MTA. The MSDN documentation is misleading in this case as it is standard not to upload to the MTA.

Here is a related article



EDIT Re-read the question a bit and saw that the blocking thread is an STA thread. Leaving the answer as CW in case it helps people hit the problem in the way described

+1


source







All Articles