web-dev-qa-db-fra.com

STAThread et multithreading

De l'article MSDN sur STAThread:

Indique que le modèle de thread COM d'une application est un appartement à thread unique (STA).

(Pour référence, c'est l'article complet .)

Appartement à un seul fil ... OK, ça m'est passé par dessus la tête. De plus, j'ai lu quelque part que, sauf si votre application utilise COM interop, cet attribut ne fait rien du tout. Alors, que fait-il exactement et en quoi cela affecte-t-il les applications multithread? Est-ce que les applications multithreads (qui incluent tous les utilisateurs de Timers et les appels de méthodes asynchrones, et pas seulement les pools de threads, etc.) doivent utiliser MTAThread, même si c'est 'juste pour être sûr'? Que font réellement STAThread et MTAThread?

102
Matthew Scharley

Le filetage des appartements est un concept COM; Si vous n'utilisez pas COM et qu'aucune des API que vous appelez n'utilise COM "sous la couverture", vous n'avez pas à vous soucier des appartements.

Si vous devez être conscient des appartements, les détails peuvent devenir n peu compliqué ; une version probablement trop simplifiée est que les objets COM étiquetés en tant que STA doivent être exécutés sur un STAThread et que les objets COM marqués MTA doivent être exécutés sur un thread MTA. À l'aide de ces règles, COM peut optimiser les appels entre ces différents objets, en évitant le marshaling où cela n'est pas nécessaire.

59
Bruce

Cela garantit que CoInitialize est appelé en spécifiant COINIT_APARTMENTTHREADED en tant que paramètre. Si vous n'utilisez aucun composant COM ni aucun contrôle ActiveX, cela n'aura aucun effet sur vous. Si vous le faites alors c'est un peu crucial.

Les contrôles qui sont threadés par appartement sont en réalité à thread unique, les appels qui leur sont passés ne peuvent être traités que dans l'appartement dans lequel ils ont été créés.

Quelques détails supplémentaires de MSDN:

Les objets créés dans un appartement à un seul thread (STA) reçoivent uniquement les appels de méthode du thread de leur appartement. Les appels sont donc sérialisés et arrivent uniquement aux limites de la file d'attente de messages (lorsque la fonction Win32 PeekMessage ou SendMessage est appelée).

Les objets créés sur un thread COM dans un appartement multithread (MTA) doivent pouvoir recevoir des appels de méthode d'autres threads à tout moment. En règle générale, vous implémentez une forme de contrôle de simultanéité dans le code d'un objet multithread à l'aide de primitives de synchronisation Win32 telles que des sections critiques, des sémaphores ou des mutex afin de protéger les données de l'objet.

Lorsqu'un objet configuré pour s'exécuter dans l'appartement neutre (NTA) est appelé par un thread qui se trouve dans une STA ou le MTA, ce thread est transféré vers le NTA. Si ce thread appelle ensuite CoInitializeEx, l'appel échoue et renvoie RPC_E_CHANGED_MODE.

3
1800 INFORMATION