Поделиться через


Помощник по отладке управляемого кода invalidApartmentStateChange

Помощник по отладке управляемого кода (MDA) invalidApartmentStateChange активируется в случае возникновения одной из следующих проблем.

  • Попытка изменить состояние контейнера СОМ в потоке, который уже был инициализирован моделью СОМ для другого состояния контейнера.

  • Непредвиденное изменение состояния контейнера СОМ в потоке.

Признаки

  • Состояние контейнера СОМ в потоке отличается от требуемого. Вследствие этого прокси могут использоваться компонентами СОМ, потоковая модель которых отличается от текущей. В свою очередь, это может стать причиной возникновения исключения InvalidCastException при вызове объекта СОМ посредством интерфейсов, не настроенных для маршалинга между контейнерами.

  • Состояние контейнера СОМ в потоке отличается от ожидаемого. Это может стать причиной возникновения исключения COMException со значением RPC_E_WRONG_THREAD для HRESULT, а также исключения InvalidCastException при вызове Вызываемая оболочка времени выполнения (RCW). Это также может привести к тому, что несколько потоков будут иметь одновременный доступ к некоторым однопотоковым компонентам СОМ, что может стать причиной повреждения или потери данных.

Причина

  • Поток был изначально инициализирован для другого состояния контейнера СОМ. Следует отметить, что установить состояние контейнера для потока можно явным или неявным образом. Чтобы определить состояние контейнера для потока явным образом, можно использовать свойство Thread.ApartmentState и методы SetApartmentState и TrySetApartmentState. Для потока, созданного неявным образом с помощью метода Start, устанавливается значение MTA, если только метод SetApartmentState не вызван до запуска потока. Главный поток приложения также инициализируется неявным образом со значением MTA, если только для основного метода не определен атрибут STAThreadAttribute.

  • В потоке вызывается метод CoUninitialize (или метод CoInitializeEx) с другой моделью параллелизма.

Решение

Следует настроить состояние контейнера потока до его запуска или применить к основному методу приложения атрибут STAThreadAttribute или MTAThreadAttribute.

Во втором случае следует изменить код, вызывающий метод CoUninitialize, чтобы вызов был отложен до завершения работы потока и прекращения использования в потоке оболочек RCW и базовых компонентов СОМ. Тем не менее, если невозможно изменить код, который вызывает метод CoUninitialize, то в этом случае не допускается использование оболочек RCW из потоков, которые не инициализированы таким образом.

Влияние на среду выполнения

Данный помощник по отладке управляемого кода не оказывает влияния на среду CLR.

Output

Состояние контейнера СОМ текущего потока, а также состояние, которое пытался применить код.

Конфигурация

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

Пример

В следующем примере кода демонстрируется ситуация, в которой может активироваться данный помощник по отладке управляемого кода.

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

См. также

Ссылки

MarshalAsAttribute

Основные понятия

Диагностика ошибок посредством управляемых помощников по отладке

Маршалинг взаимодействия