title: Why is Thread.Join not letting through COM messages?
body: <p>I am running some multi-threaded code that does the following.</p>
  
  <ol>
  <li>On an STA thread, I create a
  'worker' thread, and run it. </li>
  <li>The STA thread then waits for the worker
  thread to exit.</li>
  <li>The worker thread calls a method on a proxy to an STA COM
  object on the STA thread, and then exits.</li>
  </ol>
  
  <p>In step 2, I'm using <code>Thread.Join()</code> to wait for the worker thread to exit.</p>
  
  <p>The documentation for <code>Thread.Join()</code> states that it <strong>blocks the calling thread until a thread terminates, while continuing to perform standard COM and SendMessage pumping</strong>.</p>
  
  <p>However, what happens is the worker thread blocks 'forever' on the COM call. The STA thread never services the COM call, while it is blocked on calling Thread.Join() on the worker thread.</p>
  
  <p>I expected the STA thread to be able to service COM calls while blocked on Thread.Join.</p>
  
  <p>Can anyone explain what might be happening here?
  <hr/>
  Here's the native callstack for the call to Thread.Join (ran VS in native code debugging mode, so differences may be due to not using WinDbg?):</p>
  
  <pre><code>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 
  </code></pre>
  
  <p>Here is the call stack shown in the <a href="http://dotnet.dzone.com/news/managed-synchronization-primit" rel="nofollow noreferrer">article</a>, for STA threads that call Thread.Join:
  It appears to diverge from what I'm seeing on the last call.</p>
  
  <pre><code>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
  </code></pre>
  
  <p>Here's the article's callstack for an MTA thread:</p>
  
  <pre><code>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
  </code></pre>