Partilhar via


invalidApartmentStateChange MDA

Nota

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

O invalidApartmentStateChange assistente de depuração gerenciado (MDS) é ativado por 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 segmento muda inesperadamente.

Sintomas

  • O estado do apartamento COM de um thread não é o que foi solicitado. Isso pode fazer com que proxies sejam usados para componentes COM que têm um modelo de threading diferente do atual. Isso, por sua vez, pode fazer com que um InvalidCastException seja lançado ao chamar o objeto COM por meio de interfaces que não estão configuradas para empacotamento entre apartamentos.

  • O estado do apartamento COM do thread é diferente do esperado. Isso pode causar um COMException com um HRESULT de RPC_E_WRONG_THREAD, bem como um InvalidCastException ao fazer chamadas em um Runtime Callable Wrapper (RCW). 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 explícita ou implicitamente. As operações explícitas incluem a Thread.ApartmentState propriedade e os SetApartmentState métodos and TrySetApartmentState . Um thread criado usando o Start método é implicitamente definido como MTA a menos que SetApartmentState seja chamado antes de o thread ser iniciado. O thread principal do aplicativo também é inicializado implicitamente a MTA 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 que ele comece 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 terminar 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 deve ser usado a partir de threads não inicializados dessa maneira.

Efeito no tempo de execução

Este MDA não tem 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