Domanda

Puoi spiegare STA e MTA con parole tue?

Inoltre, quali sono i thread degli appartamenti e riguardano solo COM? In tal caso, perché?

È stato utile?

Soluzione

Il modello di threading COM è chiamato " appartamento " modello, in cui il contesto di esecuzione degli oggetti COM inizializzati è associato a un singolo thread (Single Thread Apartment) o molti thread (Multi Thread Apartment). In questo modello, un oggetto COM, una volta inizializzato in un appartamento, fa parte di quell'appartamento per la durata del suo runtime.

Il modello STA viene utilizzato per oggetti COM che non sono thread-safe. Ciò significa che non gestiscono la propria sincronizzazione. Un uso comune di questo è un componente dell'interfaccia utente. Pertanto, se un altro thread deve interagire con l'oggetto (come premere un pulsante in un modulo), il messaggio viene inviato al thread STA. Il sistema di pompaggio dei messaggi di Windows Form ne è un esempio.

Se l'oggetto COM è in grado di gestire la propria sincronizzazione, è possibile utilizzare il modello MTA in cui più thread possono interagire con l'oggetto senza chiamate con marshalling.

Altri suggerimenti

Dipende da come vengono gestite le chiamate agli oggetti e da quanta protezione hanno bisogno. Gli oggetti COM possono chiedere al runtime di proteggerli dall'essere richiamati da più thread contemporaneamente; quelli che non possono potenzialmente essere chiamati contemporaneamente da thread diversi, quindi devono proteggere i propri dati.

Inoltre, è necessario che il runtime impedisca a una chiamata di oggetto COM di bloccare l'interfaccia utente, se viene effettuata una chiamata da un thread dell'interfaccia utente.

Un appartamento è un luogo dove gli oggetti possono vivere e contengono uno o più thread. L'appartamento definisce cosa succede quando vengono effettuate le chiamate. Le chiamate agli oggetti in un appartamento verranno ricevute ed elaborate su qualsiasi thread in quell'appartamento, con l'eccezione che una chiamata da un thread già nell'appartamento giusto viene elaborata da sola (ovvero una chiamata diretta all'oggetto).

I thread possono trovarsi in un appartamento a thread singolo (nel qual caso sono l'unico thread in quell'appartamento) o in un appartamento a thread multipli. Specificare quale quando il thread inizializza COM per quel thread.

La STA è principalmente per la compatibilità con l'interfaccia utente, che è legata a un thread specifico. Un STA riceve le notifiche delle chiamate da elaborare ricevendo un messaggio da una finestra nascosta; quando effettua una chiamata in uscita, avvia un ciclo di messaggi modale per impedire l'elaborazione di altri messaggi della finestra. Puoi specificare un filtro messaggi da chiamare, in modo che l'applicazione possa rispondere ad altri messaggi.

Al contrario, tutti i thread MTA condividono un singolo MTA per il processo. COM può avviare un nuovo thread di lavoro per gestire una chiamata in arrivo se non sono disponibili thread, fino a un limite di pool. I thread che effettuano chiamate in uscita semplicemente bloccano.

Per semplicità considereremo solo gli oggetti implementati nelle DLL, che pubblicizzano nel registro ciò che supportano, impostando il valore ThreadingModel per la chiave della loro classe. Esistono quattro opzioni:

  • Thread principale (valore ThreadingModel non presente). L'oggetto viene creato sul thread dell'interfaccia utente principale dell'host e tutte le chiamate vengono indirizzate a quel thread. La factory di classe verrà chiamata solo su quel thread.
  • Appartamento . Ciò indica che la classe può essere eseguita su qualsiasi thread in modalità a thread singolo. Se il thread che lo crea è un thread STA, l'oggetto verrà eseguito su quel thread, altrimenti verrà creato nello STA principale - se non esiste STA principale, verrà creato un thread STA per esso. (Ciò significa che i thread MTA che creano oggetti Apartment eseguiranno il marshalling di tutte le chiamate a un thread diverso.) Il factory di classe può essere chiamato contemporaneamente da più thread STA, quindi deve proteggere i suoi dati interni da questo.
  • libero . Ciò indica una classe progettata per l'esecuzione nell'MTA. Verrà sempre caricato nell'MTA, anche se creato da un thread STA, il che significa di nuovo che le chiamate del thread STA verranno raggruppate. Questo perché un oggetto Free è generalmente scritto con l'aspettativa che possa bloccarsi.
  • Entrambi . Queste classi sono flessibili e si caricano in qualsiasi appartamento da cui sono state create. Devono essere scritti per soddisfare entrambi i set di requisiti, tuttavia: devono proteggere il loro stato interno da chiamate simultanee, nel caso in cui siano caricati nell'MTA, ma non devono bloccare, nel caso in cui siano caricati in uno STA.

Da .NET Framework, in pratica basta usare [STAThread] su qualsiasi thread che crea l'interfaccia utente. I thread di lavoro devono utilizzare l'MTA, a meno che non utilizzino componenti COM con marchio Appartamento , nel qual caso utilizzare STA per evitare problemi di overhead e scalabilità di marshalling se lo stesso componente viene chiamato da più thread ( poiché ogni thread dovrà attendere a sua volta il componente). È molto più semplice se si utilizza un oggetto COM separato per thread, indipendentemente dal fatto che il componente sia in STA o MTA.

Trovo che le spiegazioni esistenti siano troppo inghiottite. Ecco la mia spiegazione in inglese semplice:

STA: Se un thread crea un oggetto COM impostato su STA (quando si chiama CoCreateXXX è possibile passare un flag che imposta l'oggetto COM sulla modalità STA), solo questo thread può accedere a questo oggetto COM (questo è ciò che significa STA - Single Threaded Apartment), l'altro thread che tenta di chiamare metodi su questo oggetto COM viene automaticamente nascosto in modalità di consegna dei messaggi al thread che crea (possiede) l'oggetto COM. Questo è molto simile al fatto che solo il thread che ha creato un controllo UI può accedervi direttamente. E questo meccanismo ha lo scopo di prevenire complicate operazioni di blocco / sblocco.

MTA: Se un thread crea un oggetto COM impostato su MTA, praticamente ogni thread può chiamare direttamente i metodi su di esso.

Questo è praticamente l'essenza. Sebbene tecnicamente ci siano alcuni dettagli che non ho menzionato, come nel paragrafo "STA", il thread del creatore deve essere esso stesso STA. Ma questo è praticamente tutto ciò che devi sapere per capire STA / MTA / NA.

STA (Single Threaded Apartment) è fondamentalmente il concetto che solo un thread interagirà con il tuo codice alla volta. Le chiamate nel tuo appartamento vengono trasferite tramite messaggi di Windows (usando una finestra non visibile). Ciò consente di mettere in coda le chiamate e attendere il completamento delle operazioni.

MTA (Multi Threaded Apartment) è il luogo in cui molti thread possono funzionare tutti contemporaneamente e l'onere è tuo sviluppatore a gestire la sicurezza dei thread.

C'è molto di più da imparare sul threading di modelli in COM, ma se hai problemi a capire cosa sono, direi che capire cos'è lo STA e come funziona sarebbe il miglior punto di partenza perché la maggior parte degli oggetti COM sono STA.

Thread appartamento, se un thread vive nello stesso appartamento dell'oggetto che sta usando, allora è un thread appartamento. Penso che questo sia solo un concetto COM perché è solo un modo di parlare degli oggetti e dei fili con cui interagiscono ...

Ogni EXE che ospita controlli COM o OLE definisce lo stato dell'appartamento. Lo stato dell'appartamento è STA predefinito (e per la maggior parte dei programmi dovrebbe essere STA).

STA : tutti i controlli OLE per necessità devono vivere in uno STA. STA significa che l'oggetto COM deve essere sempre manipolato sul thread dell'interfaccia utente e non può essere passato ad altri thread (proprio come qualsiasi elemento dell'interfaccia utente in MFC). Tuttavia, il tuo programma può avere ancora molti thread.

MTA : puoi manipolare l'oggetto COM su qualsiasi thread nel tuo programma.

Come intendo, l'appartamento viene utilizzato per proteggere gli oggetti COM da problemi multi-thread.

Se un oggetto COM non è thread-safe, dovrebbe dichiararlo come oggetto STA. Quindi solo il thread che lo crea può accedervi. Il thread di creazione dovrebbe dichiararsi come thread STA. Sotto il cofano, il thread memorizza le informazioni STA nel suo TLS (Thread Local Storage). Chiamiamo questo comportamento in quanto il thread entra in un appartamento STA. Quando altri thread vogliono accedere a questo oggetto COM, dovrebbe eseguire il marshalling dell'accesso al thread di creazione. Fondamentalmente, il thread di creazione utilizza il meccanismo dei messaggi per elaborare le chiamate in entrata.

Se un oggetto COM è thread-safe, dovrebbe dichiararlo come oggetto MTA. L'oggetto MTA è accessibile da più thread.

Il codice che chiama le DLL degli oggetti COM (ad esempio, per leggere i file di dati proprietari), potrebbe funzionare bene in un'interfaccia utente ma appendere misteriosamente a un servizio. Il motivo è che a partire dalle interfacce utente .Net 2.0 assumono STA (thread-safe) mentre i servizi assumono MTA ((prima, i servizi assumevano STA). La necessità di creare un thread STA per ogni chiamata COM in un servizio può aggiungere un notevole sovraccarico.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top