Freigeben über


invalidApartmentStateChange-MDA

Hinweis

Dieser Artikel gilt für das .NET Framework. Sie gilt nicht für neuere Implementierungen von .NET, einschließlich .NET 6 und höherer Versionen.

Der invalidApartmentStateChange-MDA (Assistent für verwaltetes Debuggen) wird durch eines der folgenden zwei Probleme aktiviert:

  • Es wird versucht, den COM-Apartmentzustand eines Threads zu ändern, der bereits von COM an einen anderen Apartmentzustand initialisiert wurde.

  • Der COM-Apartmentzustand eines Threads verändert sich unerwartet.

Symptome

  • Der COM-Apartmentzustand eines Threads ist nicht das, was angefordert wurde. Dies kann möglicherweise dazu führen, dass Proxys für COM-Komponenten verwendet werden, die ein anderes Threadmodell als das aktuelle aufweisen. Dies wiederum kann dazu führen, dass ein InvalidCastException ausgelöst wird, wenn das COM-Objekt über Schnittstellen aufgerufen wird, die nicht für das apartmentübergreifende Marshalling eingerichtet sind.

  • Der COM-Apartmentzustand des Threads ist anders als erwartet. Dies kann dazu führen, dass eine COMException mit einem HRESULT von RPC_E_WRONG_THREAD sowie ein InvalidCastException ausgelöst wird, wenn ein Runtime Callable Wrapper (RCW) aufgerufen wird. Dies kann auch dazu führen, dass mehrere Threads gleichzeitig auf einige Singlethread-COM-Komponenten zugreifen können, was zu einer Beschädigung oder einem Verlust von Daten führen kann.

Ursache

  • Der Thread wurde zuvor in einen anderen COM-Apartmentzustand initialisiert. Beachten Sie, dass ein Apartmentzustand eines Threads explizit oder implizit festgelegt werden kann. Zu den expliziten Vorgängen zählen die Thread.ApartmentState-Eigenschaft und die SetApartmentState- und TrySetApartmentState-Methoden. Ein Thread, der mit der Start-Methode erstellt wurde, wird implizit auf MTA festgelegt, wenn SetApartmentState vor dem Start des Threads aufgerufen wird. Der Hauptthread der Anwendung wird ebenfalls implizit auf MTA initialisiert, sofern das STAThreadAttribute-Attribut für die Hauptmethode angegeben ist.

  • Die CoUninitialize-Methode (oder die CoInitializeEx-Methode) wird mit einem anderen Parallelitätsmodell für den Thread aufgerufen.

Lösung

Legen Sie den Apartmentzustand des Threads fest, bevor die Ausführung beginnt, oder wenden Sie entweder das STAThreadAttribute- oder das MTAThreadAttribute-Attribut auf die Hauptmethode der Anwendung an.

Hinsichtlich der zweiten Ursache sollte der Code, der die CoUninitialize-Methode aufruft, idealerweise geändert werden, um den Aufruf zu verzögern, bis der Thread beendet wird und keine RCWs und ihre zugrunde liegenden COM-Komponenten noch vom Thread verwendet werden. Sollte es jedoch nicht möglich sein, den Code zu ändern, der die CoUninitialize-Methode aufruft, dann sollten keine RCWs aus Threads verwendet werden, die auf diese Weise nicht initialisiert werden.

Auswirkungen auf die Laufzeit

Dieser MDA hat keine Auswirkungen auf die CLR.

Ausgabe

Der COM-Apartmentzustand des aktuellen Threads und der Zustand, den der Code versucht hat anzuwenden.

Konfiguration

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

Beispiel

Im folgenden Codebeispiel wird eine Situation veranschaulicht, die zum Aktivieren dieses MDA führen kann.

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

Weitere Informationen