Respuestas:
El modelo de subprocesamiento COM se denomina modelo de "departamento", donde el contexto de ejecución de los objetos COM inicializados está asociado con un subproceso único (departamento de subprocesos simples) o con muchos subprocesos (departamento de subprocesos múltiples). En este modelo, un objeto COM, una vez inicializado en un departamento, forma parte de ese departamento durante el tiempo de ejecución.
El modelo STA se usa 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 de la interfaz de usuario. Entonces, si otro hilo necesita interactuar con el objeto (como presionar un botón en un formulario), el mensaje se ordena 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, entonces el modelo MTA se puede usar donde múltiples hilos pueden interactuar con el objeto sin llamadas ordenadas.
Todo depende de 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 ser invocados por múltiples hilos al mismo tiempo; aquellos que no pueden ser potencialmente llamados simultáneamente de diferentes hilos, por lo que deben proteger sus propios datos.
Además, también es necesario que el tiempo de ejecución evite que una llamada de objeto COM bloquee la interfaz de usuario, si se realiza una llamada desde un subproceso de interfaz de usuario.
Un departamento es un lugar para que vivan los objetos y contienen uno o más hilos. El apartamento define lo que sucede cuando se realizan llamadas. Las llamadas a objetos en un departamento se recibirán y procesarán en cualquier subproceso en ese departamento, con la excepción de que una llamada de un subproceso que ya se encuentra en el departamento correcto se procesa por sí misma (es decir, una llamada directa al objeto).
Los subprocesos pueden estar en un departamento de subprocesos simples (en cuyo caso son el único subproceso en ese departamento) o en un departamento de subprocesos múltiples. Especifican qué cuando el hilo inicializa COM para ese hilo.
El STA es principalmente por 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 ventana. Puede especificar que se llame a un filtro de mensajes para que su aplicación pueda responder a otros mensajes.
Por el contrario, todos los hilos 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 realizan 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 ThreadingModel
valor para la clave de su clase. Hay cuatro opciones:
ThreadingModel
valor no presente). El objeto se crea en el subproceso de interfaz de usuario principal del host y todas las llamadas se ordenan a ese subproceso. La fábrica de clases solo se llamará en ese hilo.Apartment
. Esto indica que la clase puede ejecutarse 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 un STA principal, se creará un subproceso STA para él. (Esto significa que los subprocesos de MTA que crean objetos de apartamento ordenarán todas las llamadas a un subproceso diferente.) La fábrica de clases puede ser llamada simultáneamente por múltiples 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 es creado por un hilo STA, lo que nuevamente significa que las llamadas del hilo STA se ordenarán. Esto se debe a que un Free
objeto generalmente se escribe con la expectativa de que puede bloquear.Both
. Estas clases son flexibles y se cargan en cualquier departamento desde el que se creen. Sin embargo, deben escribirse para ajustarse a ambos conjuntos de requisitos: deben proteger su estado interno contra llamadas concurrentes, en caso de que se carguen en el MTA, pero no deben bloquearse, en caso de que se carguen en una STA.Desde .NET Framework, básicamente utilícelo [STAThread]
en cualquier hilo que cree UI. Los subprocesos de los trabajadores deben usar el MTA, a menos que vayan a usar Apartment
componentes COM marcados, en cuyo caso use el STA para evitar la sobrecarga y problemas de escalabilidad si se llama al mismo componente desde varios subprocesos (ya que cada subproceso tendrá que esperar 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 STA o MTA.
Encuentro las explicaciones existentes demasiado engullidas. Aquí está mi explicación en inglés simple:
STA: si un subproceso crea un objeto COM que está configurado en STA (al llamar a CoCreateXXX puede pasar un indicador que establece el objeto COM en el modo STA), entonces solo este subproceso puede acceder a este objeto COM (eso es lo que significa STA - Single Threaded Apartment ), otro hilo que intenta llamar a métodos en este objeto COM se encuentra silenciosamente convertido en entregar mensajes al hilo 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 operaciones complicadas de bloqueo / desbloqueo.
MTA: si un subproceso crea un objeto COM configurado como MTA, prácticamente todos los subprocesos pueden llamar directamente a los métodos que contiene.
Eso es más o menos 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 todo lo que tiene que saber para comprender STA / MTA / NA.
STA (Single Threaded Apartment) es básicamente el concepto de que solo un hilo interactuará con su código a la vez. Las llamadas a su apartamento se organizan a través de 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 operar todos al mismo tiempo y la responsabilidad recae sobre usted como desarrollador para manejar la seguridad del subproceso.
Hay mucho más que aprender sobre el enhebrado de modelos en COM, pero si tiene problemas para comprender cuáles son, entonces diría que comprender qué es el STA y cómo funciona sería el mejor punto de partida porque la mayoría de los objetos COM son STA.
Subprocesos de apartamento, si un subproceso vive en el mismo departamento que el objeto que está utilizando, entonces es un subproceso 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 del apartamento. El estado del departamento es STA por defecto (y para la mayoría de los programas debería ser STA).
STA : todos los controles OLE por necesidad deben vivir en una STA. STA significa que su objeto COM siempre debe manipularse en el subproceso de la interfaz de usuario y no puede pasarse a otros subprocesos (al igual que cualquier elemento de la interfaz de usuario en MFC). Sin embargo, su programa aún puede tener muchos hilos.
MTA : puede manipular el objeto COM en cualquier subproceso de su programa.
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 a él. El hilo de creación debería declararse como un hilo STA. Debajo del capó, el hilo almacena la información de STA en su TLS (Thread Local Storage). Llamamos a este comportamiento como que el hilo ingresa a un departamento 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 mediante subprocesos múltiples.
El código que llama 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 .Net 2.0 las interfaces de usuario asumen STA (seguro para subprocesos) mientras que los servicios asumen MTA ((antes de eso, los servicios asumen STA). Tener que crear un subproceso STA para cada llamada COM en un servicio puede agregar una sobrecarga significativa.