STAThread et multithreading
-
03-07-2019 - |
Question
Extrait de l'article MSDN sur STAThread:
Indique que le modèle de threading COM d'une application est un appartement à un seul thread (STA).
(Pour référence, il s'agit de l'intégralité de l'article .)
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? Les applications multithreads (qui incluent tout ce qui concerne les utilisateurs de Timer
aux appels de méthodes asynchrones, et pas seulement les pools de threads, etc.) doivent-elles utiliser MTAThread, même si c'est 'juste pour être sûr'? Que font réellement STAThread et MTAThread?
La solution
Le threading d'appartement est un concept COM; Si vous n'utilisez pas COM et qu'aucune des API que vous appelez n'utilise COM "sous les couvertures", vous n'avez pas à vous soucier des appartements.
Si vous devez être conscient des appartements, vous pouvez obtenir les détails un 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. En utilisant ces règles, COM peut optimiser les appels entre ces différents objets, en évitant le marshaling où cela n’est pas nécessaire.
Autres conseils
Cela permet de garantir que CoInitialize
est appelé en spécifiant COINIT_APARTMENTTHREADED en tant que paramètre. Si vous n'utilisez pas de composants COM ou de contrôles ActiveX, cela n'aura aucun effet sur vous. Si vous le faites alors c'est un peu crucial.
Les contrôles qui sont des threads d'appartement sont effectivement à 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 fournis par MSDN:
Objets créés dans un seul thread apartment (STA) recevoir des appels de méthode seulement du fil de leur appartement, donc les appels sont sérialisés et arrivent seulement aux limites de la file de messages (lorsque le Fonction Win32 PeekMessage ou SendMessage est appelé).
Objets créés sur un thread COM dans un appartement multithread (MTA) doit être capable de recevoir des appels de méthode de d'autres discussions à tout moment. Vous voudriez généralement mettre en œuvre une forme de contrôle de concurrence dans un multithread code de l'objet utilisant Win32 primitives de synchronisation telles que sections critiques, sémaphores, ou mutex pour aider à protéger l'objet Les données.
Quand un objet configuré pour courir dans l'appartement fileté neutre (NTA) est appelé par un thread qui est dans soit un STA ou le MTA, ce fil transferts à la NTA. Si ce fil appelle ensuite CoInitializeEx, le appel échoue et retourne RPC_E_CHANGED_MODE.
STAThread est écrit avant la fonction principale d'un projet d'interface graphique C #. Cela ne fait que permettre au programme de créer un seul thread.