Почему Thread.Join не пропускает сообщения COM? - PullRequest
2 голосов
/ 21 августа 2009

Я использую многопоточный код, который выполняет следующие действия.

  1. В потоке STA я создаю 'рабочий' поток, и запустите его.
  2. Затем поток STA ожидает работника нить для выхода.
  3. Рабочий поток вызывает метод на прокси для STA COM объект в потоке STA и затем завершается.

На шаге 2 я использую Thread.Join() для ожидания выхода рабочего потока.

Документация для Thread.Join() гласит, что она блокирует вызывающий поток до тех пор, пока поток не завершится, продолжая при этом выполнять стандартную COM и перекачку SendMessage .

Тем не менее, происходит то, что рабочий поток блокируется навсегда при вызове COM. Поток STA никогда не обслуживает вызов COM, пока он блокируется при вызове Thread.Join () в рабочем потоке.

Я ожидал, что поток STA сможет обслуживать вызовы COM, пока он заблокирован в Thread.Join.

Может кто-нибудь объяснить, что здесь может происходить? <Ч /> Вот родной стек вызовов для вызова 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 

Вот стек вызовов, показанный в статье , для потоков STA, которые вызывают Thread.Join: Кажется, это отличается от того, что я вижу на последнем звонке.

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 Ответ

1 голос
/ 21 августа 2009

Работает ли ваш рабочий поток в квартире MTA? Thread.Join не будет выполнять прокачку, если текущая квартира является MTA. Документация по MSDN вводит в заблуждение в этом случае, потому что это стандартно, чтобы не закачивать MTA.

Вот статья на эту тему

РЕДАКТИРОВАТЬ Перечитайте вопрос немного и увидите, что блокирующий поток является потоком STA. Оставьте ответ как CW на случай, если он поможет людям решить проблему описанным способом

...