STAThread y multihilo

102

Del artículo de MSDN sobre STAThread:

Indica que el modelo de subprocesos COM para una aplicación es un apartamento de un solo subproceso (STA).

(Como referencia, ese es el artículo completo ).

Apartamento de un solo hilo ... OK, eso pasó por encima de mi cabeza. Además, leí en alguna parte que, a menos que su aplicación use la interoperabilidad COM, este atributo en realidad no hace nada en absoluto. Entonces, ¿qué hace exactamente y cómo afecta a las aplicaciones multiproceso? ¿Deberían las aplicaciones multiproceso (que incluyen cualquier cosa, desde cualquiera que use Timers hasta llamadas a métodos asincrónicos, no solo grupos de subprocesos y similares) usar MTAThread, incluso si es 'solo para estar seguro'? ¿Qué hacen realmente STAThread y MTAThread?

Matthew Scharley
fuente

Respuestas:

60

El subproceso de apartamento es un concepto COM; si no está usando COM, y ninguna de las API que llama usa COM "bajo las sábanas", entonces no necesita preocuparse por los apartamentos.

Si necesita estar al tanto de los apartamentos, los detalles pueden complicarse un poco ; una versión probablemente demasiado simplificada es que los objetos COM etiquetados como STA deben ejecutarse en un STAThread y los objetos COM marcados como MTA deben ejecutarse en un hilo MTA. Usando estas reglas, COM puede optimizar las llamadas entre estos diferentes objetos, evitando la clasificación donde no es necesario.

Bruce
fuente
7
Eso está muy simplificado. Los objetos multiproceso pueden ejecutarse en cualquier subproceso. Los objetos con hilos de apartamentos solo pueden ejecutarse en el apartamento en el que se crearon.
1800 INFORMACIÓN
28
Una llamada desde un objeto STA en un subproceso STA, a un objeto MTA, se calculará en un subproceso MTA (a menos que el objeto MTA implemente el contador de referencias de subproceso libre). Como dije, los detalles pueden complicarse. (Trabajé en el equipo COM durante varios años con una sonrisa )
Bruce
9
A veces debe tener en cuenta esto incluso si no está utilizando COM directamente. Un subproceso debe utilizar el modelo Apartamento de subproceso único si muestra ventanas gráficas. Es por eso que [STAThread] siempre se muestra encima del método principal en una aplicación de Windows Forms.
Justin Ethier
6
¿No podría algo como un cuadro de diálogo Fuente o Archivo usar COM sin que usted lo sepa? Asumiría que lo hacen internamente, ¿no significa eso que casi cualquier aplicación de Windows Forms requeriría que se estableciera STAThread? Perdone mi suposición ingenua ya que en realidad no he hecho programación COM.
Brett Ryan
4
Una respuesta más detallada para aquellos que estén interesados: stackoverflow.com/questions/4154429/apartmentstate-for-dummies
jgauffin
3

Lo que hace eso se asegura que CoInitializese llama especificando COINIT_APARTMENTTHREADED como parámetro. Si no utiliza ningún componente COM o controles ActiveX, no tendrá ningún efecto en usted. Si lo hace, entonces es crucial.

Los controles que son subprocesos de apartamentos son efectivamente de un solo subproceso, las llamadas realizadas a ellos solo se pueden procesar en el departamento en el que se crearon.

Algunos detalles más de MSDN:

Los objetos creados en un apartamento de un solo subproceso (STA) reciben llamadas de método solo desde el hilo de su apartamento, por lo que las llamadas se serializan y llegan solo a los límites de la cola de mensajes (cuando se llama a la función Win32 PeekMessage o SendMessage).

Los objetos creados en un subproceso COM en un apartamento multiproceso (MTA) deben poder recibir llamadas a métodos de otros subprocesos en cualquier momento. Normalmente, implementaría alguna forma de control de simultaneidad en el código de un objeto multiproceso utilizando primitivas de sincronización de Win32 como secciones críticas, semáforos o mutex para ayudar a proteger los datos del objeto.

Cuando un objeto que está configurado para ejecutarse en el apartamento de subprocesos neutros (NTA) es llamado por un subproceso que está en un STA o el MTA, ese subproceso se transfiere al NTA. Si este hilo llama posteriormente a CoInitializeEx, la llamada falla y devuelve RPC_E_CHANGED_MODE.

1800 INFORMACIÓN
fuente
El artículo de MSDN es útil desde una perspectiva COM, pero ¿puede decirme cuándo llama .NET CoInitialize()en respuesta al STAThreadatributo / ApartmentState? Nota: El artículo sobre MSDN está aquí: función CoInitializeEx .
jrh
¿ Se usa thread-> SetApartmentCoInitialize() internamente? Seguí el atributo STAThread hasta allí, pero el rastro se ha enfriado (no puedo encontrar la fuente Thread::SetApartment). ¿La clase Thread de thread.h (el COM thread.h) está documentada en algún lugar? ¿Es MFC, ATL o algo más?
jrh
@jrh No conozco más detalles que eso, lo siento
1800 INFORMACIÓN
-15

STAThread se escribe antes que la función Main de un proyecto de GUI de C #. No hace nada más que permite que el programa cree un solo hilo.

Zeinth
fuente