STAThread e multithreading


102

Dall'articolo MSDN su STAThread:

Indica che il modello di threading COM per un'applicazione è un apartment a thread singolo (STA).

(Per riferimento, questo è l'intero articolo .)

Appartamento a thread singolo ... OK, mi è passato per la testa. Inoltre, ho letto da qualche parte che a meno che la tua applicazione non utilizzi l'interoperabilità COM, questo attributo in realtà non fa nulla. Quindi cosa fa esattamente e come influisce sulle applicazioni multithread? Le applicazioni multithread (che includono qualsiasi cosa da chiunque usi Timers a chiamate di metodi asincrone, non solo threadpool e simili) dovrebbero usare MTAThread, anche se è "solo per essere sicuri"? Cosa fanno effettivamente STAThread e MTAThread?

Risposte:


60

Il threading degli appartamenti è un concetto COM; se non stai usando COM e nessuna delle API che chiami usa COM "sotto le coperte", allora non devi preoccuparti degli appartamenti.

Se devi essere a conoscenza degli appartamenti, i dettagli possono diventare un po 'complicati ; una versione probabilmente semplificata è che gli oggetti COM etichettati come STA devono essere eseguiti su uno STAThread e gli oggetti COM contrassegnati MTA devono essere eseguiti su un thread MTA. Utilizzando queste regole, COM può ottimizzare le chiamate tra questi diversi oggetti, evitando il marshalling dove non è necessario.


7
Questo è semplicissimo. Gli oggetti multithread possono essere eseguiti in qualsiasi thread. Gli oggetti filettati degli appartamenti possono essere eseguiti solo nell'appartamento in cui sono stati creati.
1800 INFORMAZIONI

28
Una chiamata da un oggetto STA su un thread STA a un oggetto MTA effettuerà il marshalling a un thread MTA (a meno che l'oggetto MTA non implementi il ​​gestore di marshalling a thread libero). Come ho detto, i dettagli possono complicarsi. (Ho lavorato nel team COM per diversi anni sorridendo )
Bruce

9
A volte è necessario esserne consapevoli anche se non si utilizza direttamente COM. Un thread deve utilizzare il modello Apartment a thread singolo se visualizza finestre grafiche. Questo è il motivo per cui [STAThread] viene sempre visualizzato sopra il metodo principale in un'applicazione Windows Form.
Justin Ethier

6
Qualcosa come una finestra di dialogo Font o File non potrebbe usare COM senza che tu lo sappia? Presumo che lo facciano internamente, non significherebbe che quasi tutte le applicazioni Windows Form richiedono l'impostazione di STAThread? Perdonate la mia ingenua supposizione perché non ho effettivamente programmato COM.
Brett Ryan,

4
Una risposta più dettagliata per coloro che sono interessati: stackoverflow.com/questions/4154429/apartmentstate-for-dummies~~V~~singular~~3rd
jgauffin

3

Ciò che fa assicura che CoInitializevenga chiamato specificando COINIT_APARTMENTTHREADED come parametro. Se non si utilizzano componenti COM o controlli ActiveX, non avrà alcun effetto su di te. Se lo fai, allora è cruciale.

I controlli che sono apartment threaded sono effettivamente single threaded, le chiamate effettuate possono essere elaborate solo nell'apartment in cui sono stati creati.

Qualche dettaglio in più da MSDN:

Gli oggetti creati in un apartment a thread singolo (STA) ricevono chiamate al metodo solo dal thread dell'apartment, quindi le chiamate vengono serializzate e arrivano solo ai limiti della coda di messaggi (quando viene chiamata la funzione PeekMessage o SendMessage Win32).

Gli oggetti creati su un thread COM in un apartment multithread (MTA) devono essere in grado di ricevere chiamate di metodo da altri thread in qualsiasi momento. In genere si implementa una qualche forma di controllo della concorrenza nel codice di un oggetto multithread utilizzando primitive di sincronizzazione Win32 come sezioni critiche, semafori o mutex per proteggere i dati dell'oggetto.

Quando un oggetto configurato per essere eseguito nell'apartment a thread neutro (NTA) viene chiamato da un thread che si trova in uno STA o nell'MTA, tale thread si trasferisce all'NTA. Se questo thread chiama successivamente CoInitializeEx, la chiamata non riesce e restituisce RPC_E_CHANGED_MODE.


L'articolo MSDN è utile dal punto di vista COM, ma puoi dirmi quando .NET chiama CoInitialize()in risposta STAThreadall'attributo / ApartmentState? Nota: l'articolo su MSDN è qui: funzione CoInitializeEx .
jrh

Vuol filettatura> SetApartment usare CoInitialize()internamente? Ho tracciato l'attributo STAThread fino in fondo ma il sentiero si è raffreddato (non riesco a trovare la fonte per Thread::SetApartment). La classe Thread da thread.h (il thread.h COM) è documentata ovunque? È MFC, ATL o qualcos'altro?
jrh

@jrh Non conosco altri dettagli oltre a questo mi dispiace
1800 INFORMAZIONI

-15

STAThread viene scritto prima della funzione Main di un progetto GUI C #. Non fa altro che consente al programma di creare un singolo thread.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.