2010-12-25 18 views
17

Se si crea un thread STA come questo: Thread.SetApartmentState(STA);, non è possibile eseguire il codice contrassegnato con l'attributo [MTAThread].Quali sono i limiti di un thread STA rispetto ai thread MTA?

Abbiamo visto [STAThread] in finestre e le applicazioni console, ma non ho mai visto il codice con l'attributo [MTAThread] e non sanno che le librerie .NET utilizza questo attributo.

La mia domanda è quali sono le limitazioni di un thread con stato appartamento impostato su STA, rispetto ai thread con stato appartamento MTA (thread .NET nativi)?

risposta

18

allora non può eseguire codice contrassegnato con [MTAThread] attributo.

Non Funziona così. Il tipo di appartamento è una proprietà di una discussione, non di un metodo. Si vede l'attributo [STAThread] applicato solo al metodo Main() di un programma .NET. Determina il tipo di appartamento del primo thread creato per eseguire il programma. Necessario perché non è possibile chiamare SetApartmentState() dopo l'esecuzione del thread. Oltre a ciò, l'attributo non ha significato, il thread rimane in uno STA per tutta la sua durata. Non vedi mai [MTAThread] perché è l'impostazione predefinita.

Un thread con STA presenta alcune limitazioni. Non può mai bloccare perché blocca e spesso blocca qualsiasi codice che tenta di chiamare un metodo di un oggetto COM threaded apartment. E deve pompare un ciclo di messaggi in modo che COM possa effettuare il marshalling della chiamata al metodo da un altro thread. Le chiamate al metodo di marshalling possono essere eseguite solo quando un thread è "inattivo", non occupato nell'esecuzione di alcun codice. Un ciclo di messaggi fornisce lo stato 'non occupato'.

Ci sono anche dei requisiti per il componente COM. È necessario supportare il marshalling, limitandosi al sottoinsieme di tipi supportati da Automation in modo che sia possibile utilizzare il marshaller standard. O fornendo una coppia proxy/stub per il marshalling personalizzato. La chiave di registro determina come viene effettuato il marshalling.

La condivisione di un oggetto con filettatura appartamento tra un STA e un thread MTA è esplicitamente supportata. Il thread STA deve crearlo, qualsiasi chiamata sul thread MTA (o altri thread STA) viene eseguito il marshalling. Ciò garantisce che il componente veda sempre le chiamate effettuate sullo stesso thread, garantendo così la sicurezza del thread. Non è richiesto alcun blocco aggiuntivo.

Ultimo ma non meno importante, se si crea un oggetto COM threaded apartment su un thread MTA, COM creerà automaticamente un thread STA per dargli una casa sicura. L'unica modalità di errore per questo è quando il componente COM non supporta il marshalling. L'unico svantaggio di farlo in questo modo è che viene effettuato il marshalling di ogni chiamata. È lento.

+2

MTAThread è l'impostazione predefinita solo in C#. In vb.net STAThread è l'impostazione predefinita. Sto solo dicendo ... perché mi ci è voluto un po 'di tempo per scoprire – DanielG

+0

Questo è accurato per un progetto in modalità console VB.NET. Violazione lorda dei requisiti STA btw, un thread STA deve pompare.I programmatori VB non hanno mai avuto la fortuna di scrivere il codice thread, l'istanza predefinita di una classe Form è un'altra trappola importante. Forse era tutto apposta :) –

0

Non penso che faccia alcuna differenza se non si utilizza COM. In tal caso, in alcuni casi, gli oggetti COM potrebbero essere accessibili solo da uno o un altro tipo di thread. Se l'oggetto COM funziona in entrambi gli appartamenti, provare a eseguire test delle prestazioni. O leggere su appartamenti COM su MSDN. Ma non penso che sia importante per le prestazioni, è piuttosto una scelta di design o qualcosa del genere.

+0

Io uso alcuni componenti 'COM' e ho bisogno di' STA'. Cambiare lo stato dell'appartamento fa ciò di cui ho bisogno. Non sono sicuro delle conseguenze. Un thread 'STA' e un thread' MTA' condividono un oggetto all'interno di un'applicazione 'ASP.NET'. – Xaqron