Share via


invalidApartmentStateChange-MDA

Aktualisiert: November 2007

Der invalidApartmentStateChange-MDA (Managed Debugging Assistant, Assistent für verwaltetes Debuggen) wird aktiviert, wenn eins der beiden folgenden Probleme auftritt:

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

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

Symptome

  • Der COM-Apartmentzustand eines Threads entspricht nicht dem angeforderten Zustand. Als Folge davon werden möglicherweise Proxys für COM-Komponenten verwendet, die ein vom aktuellen Threadmodell abweichendes Modell aufweisen. Dies wiederum kann zum Auslösen einer InvalidCastException führen, wenn das COM-Objekt über Schnittstellen aufgerufen wird, die nicht für plattformübergreifendes Marshalling eingerichtet sind.

  • Der COM-Apartmentzustand des Threads ist anders als erwartet. Dies kann zu einem COMException HRESULT mit dem Wert RPC_E_WRONG_THREAD sowie zu einer InvalidCastException führen, wenn Aufrufe in einen Runtime Callable Wrapper (RCW) (RCW) erfolgen. Es kann auch dazu kommen, dass auf einige Singlethread-COM-Komponenten gleichzeitig durch mehrere Threads zugegriffen wird. Dies kann zur Beschädigung oder zum Verlust von Daten führen.

Ursache

  • Der Thread wurde zuvor mit einem anderen COM-Apartmentzustand initialisiert. Beachten Sie, dass der Apartmentzustand eines Threads entweder explizit oder implizit festgelegt werden kann. Zu den expliziten Vorgängen zählen die Thread.ApartmentState-Eigenschaft, die SetApartmentState-Methode und die TrySetApartmentState-Methode. Für einen mit der Start-Methode erstellten Thread wird implizit MTA festgelegt, es sei denn, vor dem Start des Threads wird SetApartmentState aufgerufen. Wenn für die Hauptmethode nicht das STAThreadAttribute-Attribut angegeben wurde, wird der Hauptthread der Anwendung ebenfalls implizit als MTA initialisiert.

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

Lösung

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

Für die zweite Ursache sollte der Code, in dem die CoUninitialize-Methode aufgerufen wird, am besten so geändert werden, dass der Aufruf verzögert wird, bis der Thread kurz vor dem Beenden steht und keine der von ihm verwendeten RCWs oder der entsprechenden zugrunde liegenden COM-Komponenten mehr in Gebrauch sind. Wenn jedoch der die CoUninitialize-Methode aufrufende Code nicht geändert werden kann, dürfen keine RCWs aus Threads verwendet werden, die auf diese Weise deinitialisiert werden.

Auswirkungen auf die Laufzeit

Dieser MDA hat keine Auswirkungen auf die CLR.

Ausgabe

Der COM-Apartmentzustand des aktuellen Threads und der Zustand, der durch den Code angewendet werden sollte.

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);
        }
    }
}

Siehe auch

Konzepte

Diagnostizieren von Fehlern mit Assistenten für verwaltetes Debuggen

Übersicht über das Interop-Marshalling

Referenz

MarshalAsAttribute