Compartilhar via


invalidApartmentStateChange MDA

O invalidApartmentStateChange Assistente de depuração gerenciada (MDS) é ativado por um dos dois problemas:

  • É feita uma tentativa de alterar o estado de apartment COM de um thread que já foi inicializado por COM para um estado diferente de apartamento.

  • O estado de apartment COM de um thread é alterado inesperadamente.

Sintomas

  • Estado de um segmento COM apartamento não é, o que foi solicitado. Isso pode causar proxies ser usado para componentes COM que tem um modelo de threading diferente do atual. Isso por sua vez pode causar um InvalidCastException para ser lançada ao chamar o objeto COM por meio de interfaces que não estão configuradas para empacotamento de cross-apartment.

  • O estado de apartment COM do thread é diferente do esperado. Isso pode causar uma COMException com um HRESULT de RPC_E_WRONG_THREAD, bem como um InvalidCastException Quando fazer chamadas em um Runtime Callable Wrapper (RCW). Isso também pode causar alguns componentes do COM single-threaded seja acessado por vários threads ao mesmo tempo, o que pode levar à corrupção ou perda de dados.

Causa

  • Anteriormente, o thread foi inicializado para um estado diferente de apartment COM. Observe que o estado apartment de um segmento pode ser definido explicitamente ou implicitamente. As operações explícitas incluem o Thread.ApartmentState propriedade e o SetApartmentState e TrySetApartmentState métodos. Um thread criado usando o Start método implicitamente é definido como MTA , a menos que SetApartmentState é chamado antes que o segmento é iniciado. O thread principal do aplicativo também implicitamente é inicializado para MTA , a menos que o STAThreadAttribute atributo é especificado no método principal.

  • O CoUninitialize método (ou o CoInitializeEx método) com uma simultaneidade diferente modelo é chamado no thread.

Resolução

Definir o estado do thread apartment antes do início da execução ou se aplicam tanto a STAThreadAttribute atributo ou o MTAThreadAttribute atributo para o método principal do aplicativo.

Para a segunda causa, idealmente, o código que chama o CoUninitialize método deve ser modificado para atrasar a chamada até que o thread está prestes a terminar e há nenhum RCWs e seus componentes de COM subjacentes ainda em uso por thread. No entanto, se não é possível modificar o código que chama o CoUninitialize método, e nenhum RCWs devem ser usado de threads que são não inicializadas no modo.

Efeito sobre o tempo de execução.

Este MDA não tem efeito sobre o CLR.

Saída

O estado de apartment COM do segmento atual e o estado em que o código estava tentando aplicar.

Configuração

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

Exemplo

O exemplo de código a seguir demonstra uma situação que pode ativar este MDA.

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

Consulte também

Referência

MarshalAsAttribute

Conceitos

Diagnosticar erros com assistentes de depuração gerenciada

Interop Marshaling