.net multithreading com apartments

.net - ¿Podría explicar STA y MTA?



multithreading com (7)

¿Puedes explicar STA y MTA con tus propias palabras?

Además, ¿cuáles son los hilos de los apartamentos? ¿Pertenecen solo a COM? Si es así, ¿por qué?


Cada EXE que aloja controles COM u OLE define su estado de apartamento. El estado del apartamento es por defecto STA (y para la mayoría de los programas debe ser STA).

STA - Todos los controles OLE por necesidad deben vivir en una STA. STA significa que su objeto COM debe manipularse siempre en el subproceso de la interfaz de usuario y no se puede pasar a otros subprocesos (como cualquier elemento de la interfaz de usuario en MFC). Sin embargo, su programa todavía puede tener muchos hilos.

MTA : puede manipular el objeto COM en cualquier subproceso de su programa.


El código que llama a las dlls de objetos COM (por ejemplo, para leer archivos de datos propietarios), puede funcionar bien en una interfaz de usuario, pero se cuelga misteriosamente de un servicio. La razón es que a partir de las interfaces de usuario .Net 2.0 se supone que es STA (seguro para subprocesos) mientras que los servicios asumen MTA ((antes de eso, se supone que los servicios son STA). Tener que crear un subproceso STA para cada llamada COM en un servicio puede agregar una sobrecarga significativa.


El modelo de subprocesos COM se denomina modelo de "apartamento", donde el contexto de ejecución de los objetos COM inicializados se asocia con un solo subproceso (Apartamento de subproceso único) o varios subprocesos (Apartamento de subprocesamiento múltiple). En este modelo, un objeto COM, una vez inicializado en un apartamento, forma parte de ese apartamento durante el tiempo de ejecución.

El modelo STA se utiliza para objetos COM que no son seguros para subprocesos. Eso significa que no manejan su propia sincronización. Un uso común de esto es un componente UI. Entonces, si otro subproceso necesita interactuar con el objeto (como presionar un botón en un formulario), el mensaje se convierte en el subproceso STA. El sistema de bombeo de mensajes de Windows Forms es un ejemplo de esto.

Si el objeto COM puede manejar su propia sincronización, entonces se puede usar el modelo MTA donde múltiples subprocesos pueden interactuar con el objeto sin llamadas ordenadas.


Encuentro las explicaciones existentes demasiado engullidas. Aquí está mi explicación en inglés simple:

STA: si un subproceso crea un objeto COM que se establece en STA (al llamar a CoCreateXXX, puede pasar un indicador que establece el objeto COM en el modo STA), solo este subproceso puede acceder a este objeto COM (eso es lo que significa STA - Apartamento con un solo hilo ), otro subproceso que intenta llamar a métodos en este objeto COM está bajo el capó y se convierte silenciosamente en entregar mensajes al subproceso que crea (posee) el objeto COM. Esto es muy parecido al hecho de que solo el hilo que creó un control de UI puede acceder a él directamente. Y este mecanismo está destinado a evitar complicadas operaciones de bloqueo / desbloqueo.

MTA: si un subproceso crea un objeto COM que se establece en MTA, casi todos los subprocesos pueden llamar directamente a los métodos.

Eso es prácticamente lo esencial. Aunque técnicamente hay algunos detalles que no mencioné, como en el párrafo ''STA'', el hilo creador debe ser STA. Pero esto es prácticamente todo lo que debe saber para comprender STA / MTA / NA.


STA (Apartamento con un solo hilo) es básicamente el concepto de que solo un hilo interactuará con su código a la vez. Las llamadas a su apartamento se calculan mediante mensajes de Windows (usando una ventana no visible). Esto permite que las llamadas se pongan en cola y esperen a que se completen las operaciones.

MTA (Multi Threaded Apartment) es donde muchos subprocesos pueden funcionar al mismo tiempo y la responsabilidad recae en usted como desarrollador para manejar la seguridad del subproceso.

Hay mucho más para aprender sobre los modelos de subprocesos en COM, pero si tiene problemas para entender qué son, entonces diría que entender qué es la STA y cómo funciona sería el mejor lugar de partida, ya que la mayoría de los objetos COM son STA.

Hilos de apartamento: si un hilo vive en el mismo apartamento que el objeto que está utilizando, entonces se trata de un hilo de apartamento. Creo que esto es solo un concepto COM porque es solo una forma de hablar sobre los objetos y los hilos con los que interactúan ...


Según tengo entendido, el ''Apartamento'' se utiliza para proteger los objetos COM de problemas de subprocesos múltiples.

Si un objeto COM no es seguro para subprocesos, debe declararlo como un objeto STA. Entonces solo el hilo que lo crea puede acceder. El subproceso de creación debe declararse como un subproceso STA. Bajo el capó, el hilo almacena la información STA en su TLS (Thread Local Storage). Llamamos a este comportamiento ya que el hilo entra en un apartamento de STA. Cuando otros subprocesos desean acceder a este objeto COM, debe ordenar el acceso al subproceso de creación. Básicamente, el hilo de creación utiliza un mecanismo de mensajes para procesar las llamadas entrantes.

Si un objeto COM es seguro para subprocesos, debe declararlo como un objeto MTA. Se puede acceder al objeto MTA por múltiples hilos.


Todo depende de cómo se manejan las llamadas a los objetos y de cuánta protección necesitan. Los objetos COM pueden pedir al tiempo de ejecución que los proteja para que no sean llamados por varios subprocesos al mismo tiempo; los que no pueden potencialmente ser llamados concurrentemente desde diferentes hilos, por lo que tienen que proteger sus propios datos.

Además, también es necesario que el tiempo de ejecución impida que una llamada de objeto COM bloquee la interfaz de usuario, si se realiza una llamada desde un subproceso de interfaz de usuario.

Un apartamento es un lugar para que los objetos vivan, y contienen uno o más hilos. El apartamento define lo que sucede cuando se hacen las llamadas. Las llamadas a objetos en un apartamento se recibirán y procesarán en cualquier subproceso de ese apartamento, con la excepción de que una llamada de un hilo que ya se encuentre en el apartamento correcto se procesa por sí misma (es decir, una llamada directa al objeto).

Los hilos pueden estar en un apartamento de un solo hilo (en cuyo caso son el único hilo de ese apartamento) o en un apartamento de varios hilos. Especifican que cuando el hilo inicializa COM para ese hilo.

La STA es principalmente para la compatibilidad con la interfaz de usuario, que está vinculada a un hilo específico. Una STA recibe notificaciones de llamadas para procesar al recibir un mensaje de ventana en una ventana oculta; cuando realiza una llamada saliente, inicia un bucle de mensaje modal para evitar que se procesen otros mensajes de la ventana. Puede especificar un filtro de mensajes para que se llame, de modo que su aplicación pueda responder a otros mensajes.

Por el contrario, todos los subprocesos de MTA comparten un solo MTA para el proceso. COM puede iniciar un nuevo subproceso de trabajo para manejar una llamada entrante si no hay subprocesos disponibles, hasta un límite de grupo. Los hilos que hacen llamadas salientes simplemente bloquean.

Para simplificar, consideraremos solo los objetos implementados en DLL, que anuncian en el registro lo que admiten, al establecer el valor de ThreadingModel para la clave de su clase. Hay cuatro opciones:

  • Hilo principal (valor de ThreadingModel no presente). El objeto se crea en el subproceso de la interfaz de usuario principal del host y todas las llamadas se agrupan en ese hilo. La clase de fábrica solo será llamada en ese hilo.
  • Apartment Esto indica que la clase se puede ejecutar en cualquier subproceso de modo de subproceso único. Si el subproceso que lo crea es un subproceso STA, el objeto se ejecutará en ese subproceso; de lo contrario, se creará en el STA principal. Si no existe STA principal, se creará un subproceso STA para él. (Esto significa que los subprocesos MTA que crean objetos de Apartamento estarán ordenando todas las llamadas a un subproceso diferente). La fábrica de clases puede ser llamada simultáneamente por varios subprocesos STA, por lo que debe proteger sus datos internos contra esto.
  • Free Esto indica una clase diseñada para ejecutarse en el MTA. Siempre se cargará en el MTA, incluso si está creado por un subproceso STA, lo que de nuevo significa que las llamadas del subproceso STA se ordenarán. Esto se debe a que un objeto Free generalmente se escribe con la expectativa de que se puede bloquear.
  • Both Estas clases son flexibles y se cargan en cualquier apartamento desde el que se crean. Sin embargo, deben escribirse para ajustarse a ambos conjuntos de requisitos: deben proteger su estado interno contra llamadas concurrentes, en caso de que estén cargadas en el MTA, pero no deben bloquearse, en caso de que estén cargadas en una STA.

Desde .NET Framework, básicamente solo use [STAThread] en cualquier hilo que cree UI. Los subprocesos de trabajo deben usar el MTA, a menos que vayan a usar componentes COM con la marca del Apartment , en cuyo caso use el STA para evitar la sobrecarga y los problemas de escalabilidad si se llama al mismo componente desde varios subprocesos (ya que cada subproceso tendrá que esperar para el componente a su vez). Es mucho más fácil si usa un objeto COM separado por subproceso, ya sea que el componente esté en la STA o el MTA.