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?
- Sur un thread STA, je crée un thread 'worker' et l'exécute.
- Le thread STA attend alors que le thread de travail sorte.
- 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
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é? –
Bonne idée. Je vais essayer ça. – mackenir