¿Podría explicar STA y MTA?

¿Puedes explicar STA y MTA con tus propias palabras?

Además, ¿qué son los hilos de apartamento y pertenecen solo a COM? Si es así, ¿por qué?

El modelo de subprocesamiento COM se denomina modelo de “apartamento”, donde el contexto de ejecución de los objetos COM inicializados se asocia con un solo subproceso (Single Thread Apartment) o con muchos subprocesos (Multi Thread Apartment). En este modelo, un objeto COM, una vez inicializado en un departamento, es 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 hilo necesita interactuar con el objeto (como presionar un botón en un formulario), entonces el mensaje se clasifica en el hilo 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, el modelo MTA se puede usar cuando se permite que varios subprocesos interactúen con el objeto sin llamadas ordenadas.

Todo se reduce a cómo se manejan las llamadas a los objetos y cuánta protección necesitan. Los objetos COM pueden pedirle al tiempo de ejecución que los proteja contra el llamado por múltiples hilos al mismo tiempo; aquellos que no pueden ser potencialmente llamados concurrentemente desde diferentes subprocesos, entonces tienen que proteger sus propios datos.

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

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

Los subprocesos pueden estar en un apartamento Single-Threaded (en este caso son el único subproceso en ese apartamento) o en un apartamento Multi-Threaded. Especifican cuál cuando el hilo inicializa COM para ese hilo.

El 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 a una ventana oculta; cuando realiza una llamada saliente, inicia un ciclo de mensaje modal para evitar que se procesen otros mensajes de la ventana. Puede especificar que se llame un filtro de mensaje para que su aplicación pueda responder a otros mensajes.

Por el contrario, todos los hilos MTA comparten un único 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 se bloquean.

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

  • Tema principal (valor de ThreadingModel no presente). El objeto se crea en el hilo de IU principal del host, y todas las llamadas se organizan en ese hilo. La fábrica de clases solo será llamada en ese hilo.
  • Apartment Esto indica que la clase puede ejecutarse en cualquier subproceso de modo de subproceso único. Si el hilo que lo crea es un hilo STA, el objeto se ejecutará en ese hilo, de lo contrario se creará en el STA principal; si no existe un STA principal, se creará un hilo STA para él. (Esto significa que los hilos MTA que crean objetos de Apartamento organizarán todas las llamadas a un hilo diferente). La fábrica de clases puede ser llamada concurrentemente por múltiples hilos 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 hilo STA, lo que significa que las llamadas del hilo STA serán ordenadas. Esto se debe a que un objeto Free generalmente se escribe con la expectativa de que puede bloquear.
  • Both . Estas clases son flexibles y se cargan en el apartamento desde el que están creadas. Sin embargo, deben escribirse para ajustarse a ambos tipos de requisitos: deben proteger su estado interno frente a llamadas simultáneas, en caso de que estén cargadas en el MTA, pero no deben bloquear, en caso de que estén cargadas en una STA.

Desde .NET Framework, básicamente solo usa [STAThread] en cualquier hilo que cree UI. Los subprocesos de trabajo deben usar el MTA, a menos que vayan a utilizar componentes COM con la marca de Apartment , en cuyo caso usan la 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 utiliza un objeto COM separado por subproceso, ya sea que el componente esté en STA o MTA.

Encuentro que las explicaciones existentes también son engorrosas. Aquí está mi explicación en inglés simple:

STA: Si un hilo crea un objeto COM que está establecido en STA (cuando llama a CoCreateXXX puede pasar un indicador que establece el objeto COM en modo STA), solo este hilo puede acceder a este objeto COM (eso es lo que significa STA – Single Threaded Apartment ), otro subproceso que trata de llamar a métodos en este objeto COM está bajo el capó convertido silenciosamente en la entrega de 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 locking / deslocking.

MTA: si un hilo crea un objeto COM que está configurado en MTA, entonces prácticamente cada hilo puede invocar métodos directamente sobre él.

Eso es básicamente lo esencial. Aunque técnicamente hay algunos detalles que no mencioné, como en el párrafo ‘STA’, el hilo del creador debe ser STA. Pero esto es todo lo que debes saber para entender STA / MTA / NA.

STA (Single Threaded Apartment) es básicamente el concepto de que solo un hilo interactuará con tu código a la vez. Las llamadas a su apartamento se clasifican a través de mensajes de Windows (usando una ventana no visible). Esto permite poner en cola las llamadas y esperar a que se completen las operaciones.

MTA (Multi Threaded Apartment) es donde muchos subprocesos pueden funcionar todos al mismo tiempo y usted tiene la responsabilidad de que el desarrollador se encargue de la seguridad del subproceso.

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

Apartment Threads, si un hilo vive en el mismo apartamento que el objeto que está utilizando, entonces es 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 …

Cada EXE que aloja controles COM u OLE define su estado de departamento. El estado del departamento es por defecto STA (y para la mayoría de los progtwigs 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 interfaz de usuario y no se puede pasar a otros subprocesos (como cualquier elemento de interfaz de usuario en MFC). Sin embargo, su progtwig todavía puede tener muchos hilos.

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

Según tengo entendido, el ‘Apartamento’ se usa 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 a él. El hilo de creación debería declararse como un hilo STA. Debajo del capó, el hilo almacena la información STA en su TLS (Thread Local Storage). Llamamos a este comportamiento como que el hilo entra en un apartamento de STA. Cuando otros subprocesos desean acceder a este objeto COM, debe ordenar el acceso al hilo 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. El objeto MTA se puede acceder por varios hilos.

El código que llama a las DLL de objetos COM (por ejemplo, para leer archivos de datos de propiedad), puede funcionar bien en una interfaz de usuario pero se cuelga misteriosamente de un servicio. El motivo es que a partir de las interfaces de usuario .Net 2.0 se supone STA (thread-safe) mientras que los servicios asumen MTA ((antes, los servicios asumían STA). Tener que crear un hilo STA para cada llamada COM en un servicio puede agregar una sobrecarga significativa.