Compartilhar via


invalidApartmentStateChange MDA

Observação

Este artigo é específico para .NET Framework. Ele não se aplica a implementações mais recentes do .NET, incluindo o .NET 6 e versões posteriores.

O invalidApartmentStateChange MDS (assistente de depuração gerenciado) é ativado por qualquer um dos dois problemas:

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

  • O estado do apartamento COM de um thread é alterado inesperadamente.

Symptoms

  • O estado do apartamento COM de um thread não é o que foi solicitado. Isso pode fazer com que os proxies sejam usados para componentes COM que tenham um modelo de threading diferente do atual. Isso, por sua vez, pode fazer com que uma InvalidCastException origem seja gerada ao chamar o objeto COM por meio de interfaces que não estão configuradas para o marshalling entre apartamentos.

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

Motivo

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

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

Resolução

Defina o estado do apartamento do thread antes de começar a ser executado ou aplique o STAThreadAttribute atributo ou o MTAThreadAttribute atributo ao 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 esteja prestes a ser encerrado e não haja RCWs e seus componentes COM subjacentes ainda em uso pelo thread. No entanto, se não for possível modificar o código que chama o CoUninitialize método, nenhum RCWs deverá ser usado de threads não inicializados dessa forma.

Efeito no Runtime

Esse MDA não tem nenhum efeito sobre o CLR.

Saída

O estado do apartamento COM do thread atual e o estado 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 esse MDA.

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

Consulte também