다음을 통해 공유


invalidApartmentStateChange MDA

메모

이 문서는 .NET Framework와 관련이 있습니다. .NET 6 이상 버전을 포함하여 .NET의 최신 구현에는 적용되지 않습니다.

invalidApartmentStateChange MDS(관리 디버깅 도우미)는 다음 두 가지 문제 중 하나에 의해 활성화됩니다.

  • COM에서 이미 초기화한 스레드의 COM 아파트 상태를 다른 아파트 상태로 변경하려고 합니다.

  • 스레드의 COM 아파트 상태가 예기치 않게 변경됩니다.

Symptoms

  • 스레드의 COM 아파트 상태는 요청된 상태가 아닙니다. 이로 인해 스레딩 모델이 현재 모델과 다른 COM 구성 요소에 프록시가 사용될 수 있습니다. 그러면 아파트 간 마샬링을 위해 설정되지 않은 인터페이스를 통해 COM 개체를 호출할 때 throw될 수 InvalidCastException 있습니다.

  • 스레드의 COM 아파트 상태가 예상과 다릅니다. 이로 인해 COMException HRESULT가 RPC_E_WRONG_THREAD InvalidCastException RCW( 런타임 호출 가능 래퍼)를 호출할 때 발생할 수 있습니다 . 이로 인해 여러 스레드에서 동시에 일부 단일 스레드 COM 구성 요소에 액세스할 수 있으므로 손상 또는 데이터 손실이 발생할 수 있습니다.

원인

  • 스레드는 이전에 다른 COM 아파트 상태로 초기화되었습니다. 스레드의 아파트 상태는 명시적으로 또는 암시적으로 설정할 수 있습니다. 명시적 작업에는 속성과 메서드가 SetApartmentStateTrySetApartmentState 포함 Thread.ApartmentState 됩니다. 메서드를 사용하여 만든 스레드는 스레드가 Start 시작되기 전에 호출되지 않는 한 SetApartmentState 암시적으로 설정 MTA 됩니다. 기본 메서드에 특성을 지정하지 않는 한 STAThreadAttribute 애플리케이션의 주 스레드도 암시적으로 초기화 MTA 됩니다.

  • CoUninitialize 다른 동시성 모델을 사용하는 메서드(또는 CoInitializeEx 메서드)가 스레드에서 호출됩니다.

해결 방법

스레드가 실행되기 전에 아파트 상태를 설정하거나 특성 또는 MTAThreadAttribute 특성을 애플리케이션의 기본 메서드에 적용 STAThreadAttribute 합니다.

두 번째 원인의 경우 스레드가 종료될 때까지 호출을 지연하도록 메서드를 호출 CoUninitialize 하는 코드를 수정해야 하며 스레드에서 여전히 사용 중인 RCW 및 해당 기본 COM 구성 요소가 없습니다. 그러나 메서드를 호출 CoUninitialize 하는 코드를 수정할 수 없는 경우 이러한 방식으로 초기화되지 않은 스레드에서 RCW를 사용하지 않아야 합니다.

런타임에 미치는 영향

이 MDA는 CLR에 영향을 주지 않습니다.

출력

현재 스레드의 COM 아파트 상태 및 코드가 적용하려는 상태입니다.

Configuration

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

예시

다음 코드 예제에서는 이 MDA를 활성화할 수 있는 상황을 보여 줍니다.

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

참고하십시오