2009-08-21 6 views
2

Je suis en cours d'exécution du code multithread qui fait ce qui suit.Pourquoi Thread.Join ne laisse pas passer les messages COM?

  1. Sur un thread STA, je crée un thread 'worker' et l'exécute.
  2. Le thread STA attend alors que le thread de travail sorte.
  3. Le thread de travail appelle une méthode sur un proxy vers un objet STA COM sur le thread STA, puis quitte.

À l'étape 2, j'utilise Thread.Join() pour attendre que le thread de travail quitte.

La documentation pour Thread.Join() indique que bloque le thread appelant jusqu'à ce qu'un thread se termine, tout en continuant à effectuer le pompage COM et SendMessage standard. Cependant, ce qui se passe est que les blocs de threads de travail sont 'forever' sur l'appel COM. Le thread STA ne traite jamais l'appel COM, alors qu'il est bloqué lors de l'appel Thread.Join() sur le thread de travail.

Je m'attendais à ce que l'unité d'exécution STA soit en mesure de traiter les appels COM tout en bloquant sur Thread.Join. Est-ce que quelqu'un peut expliquer ce qui pourrait se passer ici?


Voici le callstack natif pour l'appel à Thread.Join (couru VS en mode débogage de code natif, donc les différences peuvent être dues à ne pas utiliser WinDbg?):

[email protected]() 
[email protected]() + 0xc bytes 
[email protected]() - 0x51 bytes 
[email protected]() + 0xd7 bytes 
ole32.dll!CCliModalLoop::BlockFn() + 0x8c bytes  
[email protected]() - 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 

Voici la pile d'appel indiqué sur la article, pour les threads STA qui appellent Thread.Join: Il semble diverger de ce que je vois sur le dernier appel.

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 

Voici le callstack de l'article pour un thread 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

Je pense que c'est très intéressant, et effrayant. Pourriez-vous joindre un débogueur natif (avec des symboles complets - Google pour "serveur de symboles Microsoft" si vous ne les avez pas déjà) et voir si la pile d'appels pour la STA Thread.Join correspond à ce qui est montré dans l'article référencé? –

+0

Bonne idée. Je vais essayer ça. – mackenir

Répondre

1

Est-ce votre thread de travail Évoluant dans un appartement MTA? Un Thread.Join n'effectuera pas de pompage si l'appartement actuel est un MTA. La documentation sur MSDN est trompeuse dans ce cas car il est standard de ne pas pomper dans un MTA.

Voici un article sur le sujet

EDIT Relisez la question un peu et vu que le fil de blocage est un thread STA. Laissant répondre comme un CW dans le cas où il aide les gens à frapper le problème de la façon décrite

+0

Thread.Join est appelé dans le thread STA. Le travailleur est le MTA je pense - juste ce qui est le défaut. Vos commentaires s'appliquent-ils toujours? – mackenir

+0

Dang.:) ________ – mackenir

+1

Répondre upvoted pour le lien indirect vers l'article de Chris Brumme, qui peut aider néanmoins ... – mackenir

Questions connexes