Compartir a través de


MDA de invalidApartmentStateChange

Actualización: noviembre 2007

El ayudante para la depuración administrada (MDA) de invalidApartmentStateChange se activa por cualquiera de estos dos problemas:

  • Se intenta cambiar el estado de apartamento COM de un subproceso que ya ha inicializado COM en un estado de apartamento distinto.

  • El estado de apartamento COM de un subproceso cambia inesperadamente.

Síntomas

  • El estado de apartamento COM de un subproceso no corresponde a la solicitud. Esto puede provocar que se utilicen proxy para componentes COM que tienen un modelo de subprocesos diferente del actual. A su vez, esto puede dar lugar a que se produzca una excepción InvalidCastException cuando se llama al objeto COM a través de interfaces no configuradas para el cálculo de referencias entre apartamentos.

  • El estado de apartamento COM del subproceso es diferente del esperado. Esto puede provocar una excepción COMException con el valor HRESULT de RPC_E_WRONG_THREAD, así como una excepción InvalidCastException al realizar las llamadas en un RCW (Contenedor al que se puede llamar en tiempo de ejecución). Esto también puede provocar que varios subprocesos obtengan acceso simultáneamente a algunos componentes COM de un único subproceso, lo que puede dar lugar a daños o a la pérdida de datos.

Motivo

  • El subproceso se inicializó previamente en un estado de apartamento COM diferente. Tenga en cuenta que el estado de apartamento de un subproceso se puede establecer explícita o implícitamente. Las operaciones explícitas incluyen la propiedad Thread.ApartmentState y los métodos SetApartmentState y TrySetApartmentState. Un subproceso creado con el método Start se establece implícitamente en MTA a menos que se llame a SetApartmentState antes de que se produzca el subproceso. El subproceso principal de la aplicación también se inicializa implícitamente en MTA a menos que se especifique el atributo STAThreadAttribute en el método principal.

  • En el subproceso se llama al método CoUninitialize (o al método CoInitializeEx) con un modelo de concurrencia diferente.

Resolución

Establezca el estado de apartamento del subproceso antes de que éste comience a ejecutarse, o bien aplique el atributo STAThreadAttribute o el atributo MTAThreadAttribute al método principal de la aplicación.

Para el segundo motivo, lo ideal sería modificar el código que llama al método CoUninitialize para que retrase la llamada hasta que el subproceso esté a punto de terminar, no haya RCW y sus componentes COM subyacentes sigan siendo utilizados por el subproceso. Sin embargo, si no es posible modificar el código que llama al método CoUninitialize, no deben utilizarse de este modo RCW de subprocesos sin inicializar.

Efecto en el tiempo de ejecución.

Este MDA no tiene efecto en el CLR.

Resultado

El estado de apartamento COM del subproceso actual y el estado que el código estaba intentando aplicar.

Configuración

<mdaConfig>
  <assistants>
    <invalidApartmentStateChange />
  </assistants>
</mdaConfig>

Ejemplo

En el siguiente ejemplo de código se muestra una situación en la que se puede activar este MDA.

using System.Threading;
namespace ApartmentStateMDA
{
    class Program
    {
        static void Main(string[] args)
        {
            Thread.CurrentThread.SetApartmentState(ApartmentState.STA);
        }
    }
}

Vea también

Conceptos

Diagnóstico de errores con ayudantes de depuraciones administradas

Información general acerca del cálculo de referencia de interoperabilidad

Referencia

MarshalAsAttribute