Udostępnij za pośrednictwem


invalidApartmentStateChange MDA

Uwaga

Ten artykuł jest specyficzny dla programu .NET Framework. Nie ma zastosowania do nowszych implementacji platformy .NET, w tym .NET 6 i nowszych wersji.

Asystent invalidApartmentStateChange zarządzanego debugowania (MDS) jest aktywowany przez jeden z dwóch problemów:

  • Podjęto próbę zmiany stanu mieszkania COM wątku, który został już zainicjowany przez COM do innego stanu mieszkania.

  • Stan mieszkania COM wątku zmienia się nieoczekiwanie.

Objawy

  • Stan mieszkania COM wątku nie jest to, czego zażądano. Może to spowodować, że serwery proxy będą używane w przypadku składników COM, które mają model wątków inny niż bieżący. Z kolei może to spowodować InvalidCastException zgłoszenie podczas wywoływania obiektu COM za pośrednictwem interfejsów, które nie są skonfigurowane do krzyżowego marshallingu.

  • Stan mieszkania COM wątku jest inny niż oczekiwano. Może to spowodować COMException z HRESULT RPC_E_WRONG_THREAD, a także InvalidCastException podczas wykonywania wywołań w wywołaniach zawijania wywoływanego środowiska uruchomieniowego (RCW). Może to również spowodować jednoczesne uzyskanie dostępu do niektórych jednowątkowych składników COM przez wiele wątków, co może prowadzić do uszkodzenia lub utraty danych.

Przyczyna

  • Wątek został wcześniej zainicjowany do innego stanu mieszkania COM. Należy pamiętać, że stan mieszkania wątku można ustawić jawnie lub niejawnie. Jawne operacje obejmują Thread.ApartmentState właściwość i SetApartmentState metody i TrySetApartmentState . Wątek utworzony przy użyciu Start metody jest niejawnie ustawiony na MTA , chyba że SetApartmentState zostanie wywołany przed uruchomieniem wątku. Główny wątek aplikacji jest również niejawnie inicjowany, MTA chyba że STAThreadAttribute atrybut jest określony w metodzie main.

  • Metoda CoUninitialize (lub CoInitializeEx metoda) z innym modelem współbieżności jest wywoływana w wątku.

Rozwiązanie

Ustaw stan mieszkania wątku przed rozpoczęciem wykonywania lub zastosuj STAThreadAttribute atrybut lub MTAThreadAttribute atrybut do głównej metody aplikacji.

W przypadku drugiej przyczyny, najlepiej, kod, który wywołuje CoUninitialize metodę, należy zmodyfikować, aby opóźnić wywołanie, dopóki wątek nie zakończy się i nie ma rcws i ich podstawowych składników COM nadal używanych przez wątek. Jeśli jednak nie można zmodyfikować kodu, który wywołuje CoUninitialize metodę, nie należy używać żadnych rcW z wątków, które są w ten sposób niezainicjowane.

Wpływ na środowisko uruchomieniowe

Ta usługa MDA nie ma wpływu na CLR.

Wyjście

Stan mieszkania COM bieżącego wątku i stan, że kod próbował zastosować.

Konfigurowanie

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

Przykład

W poniższym przykładzie kodu pokazano sytuację, która może aktywować tę usługę MDA.

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

Zobacz też