2010-04-26 4 views
4

Je travaille sur une application qui communique avec un périphérique externe via une bibliothèque COM tierce. Je tente d'avoir toutes les communications à l'appareil passent par un fil de fond à la fois pour éviter les problèmes de communication de vider mon application et de se débarrasser de certaines autres complexités introduites par la communication dans le fil de l'interface utilisateur. Le problème est que chaque fois que quelque chose arrive qui bloque le thread principal de l'IU (c'est-à-dire que MessageBox.Show est appelé ou même simplement déplace la fenêtre sur l'écran), la communication avec le périphérique sur le thread d'arrière-plan s'arrête également.Un thread d'interface utilisateur bloque un thread d'arrière-plan appelant un objet COM

Existe-t-il un moyen (à part un processus totalement séparé) de séparer suffisamment les deux fils pour qu'ils n'interfèrent pas les uns avec les autres? (Remarque, le même code avec quelques calculs mathématiques pour ralentir un peu fonctionne très bien, c'est seulement quand j'utilise la bibliothèque COM que j'ai le problème)

+3

Cela semble très étrange. Sans voir votre code, il est difficile de savoir avec certitude pourquoi le fait que le thread de l'interface utilisateur soit occupé ralentit votre autre thread. Y a-t-il quelque chose sur le thread de travail qui pourrait éventuellement attendre que le thread UI fasse quelque chose? –

+1

Votre thread d'arrière-plan indique-t-il à l'interface utilisateur d'ouvrir une boîte de message en utilisant 'Invoke'? – Paolo

+0

@Paolo, On dirait que c'est quelque chose qui se produirait beaucoup plus fréquemment que d'ouvrir une boîte de message ou quelque chose comme ça. Vraisemblablement, il n'ouvre pas autant de boîtes de messages qui saisissent la fenêtre et la déplacent, provoquant un ralentissement. :) –

Répondre

11

Le comportement que vous observez peut être expliqué si le deux conditions sont vraies.

  • La 3ème bibliothèque partie COM est conçu pour être exécuté dans un seul appartement fileté
  • Vous créez une instance d'une classe de la bibliothèque sur le thread d'interface utilisateur

Depuis les pistes de thread d'interface utilisateur dans un STA (single threaded apartment) et la classe COM a été créée sur ce thread alors tous les appels à la classe provenant d'un thread autre que le thread UI seront rassemblés sur le thread UI lui-même. Si le thread UI est bloqué, tous les appels à la classe COM seront également bloqués.

+1

Cela a fait l'affaire. L'objet COM était en cours de création dans le thread d'interface utilisateur avant d'être transmis au thread de travail. Quand j'ai déplacé cela dans le fil de travail lui-même, le problème est parti. – AlphaKilo

2

Je voudrais compléter la réponse de Brian.

Se pourrait-il que vous oubliez d'appeler TrySetApartmentState(ApartmentState.STA) pour votre fil de travail? Si c'est le cas, je crois que votre thread de travail s'exécute dans MTA par défaut et tous les objets STA sont créés sur un thread STA séparé (peut-être même thread principal de l'interface utilisateur). Vous devez vous assurer que votre thread de travail se joint à un STA et voir si cela aide.

À part cela, les objets COM peuvent être enregistrés en tant que STA principal. IIRC, c'est rare. Objets Main-STA DOIT vivre dans le thread UI principal. Si cela vous arrive, je crois que votre seule option est de recourir au processus de travail au lieu d'un thread de travail.

Questions connexes