Помощник по отладке управляемого кода invalidApartmentStateChange
Примечание.
Эта статья относится к .NET Framework. Он не применяется к более новым реализациям .NET, включая .NET 6 и более поздние версии.
Помощник по отладке управляемого кода (MDA) invalidApartmentStateChange
активируется при возникновении одной из двух следующих проблем.
Предпринята попытка изменить состояние подразделения COM потока, который уже был инициализирован COM в другом состоянии подразделения.
Неожиданное изменение состояния подразделения COM потока.
Симптомы
Состояние подразделения COM отличается от запрошенного. Это может привести к использованию прокси-серверов для COM-компонентов, имеющих потоковую модель, отличную от текущей. Это, в свою очередь, может вызвать InvalidCastException исключение при вызове COM-объекта через интерфейсы, которые не настроены для маршаллинга между квартирами.
Состояние подразделения COM потока отличается от ожидаемого. Это может привести к COMException с HRESULT RPC_E_WRONG_THREAD, а также InvalidCastException при вызовах вызываемой оболочки времени выполнения (RCW). Кроме того, сразу несколько потоков могут одновременно осуществлять доступ к некоторым однопоточным COM-компонентам, что может привести к повреждению или потере данных.
Причина
Поток ранее был инициализирован в другом состоянии подразделения СОМ. Обратите внимание, что состояние потока подразделения может быть задано явным или неявным образом. Явные операции содержат свойство Thread.ApartmentState и методы SetApartmentState и TrySetApartmentState. Поток, созданный с помощью метода Start, неявно задан как MTA до тех пор, пока SetApartmentState не будет вызван до запуска потока. Основной поток приложения также неявно инициализирован как MTA до тех пор, пока в основном методе не будет указан атрибут STAThreadAttribute.
В потоке вызван метод
CoUninitialize
(или методCoInitializeEx
) с другой моделью параллелизма.
Разрешение
Задайте состояние подразделения потока перед началом его выполнения либо примените атрибут STAThreadAttribute или MTAThreadAttribute атрибут к основному методу приложения.
Во втором случае в идеале код, вызывающий метод CoUninitialize
, следует изменить для задержки вызова до тех пор, пока поток не будет завершен и не перестанет использовать RCW и базовые СОМ-компоненты. Однако если не удается изменить код, который вызывает методCoUninitialize
, то нельзя использовать RCW из потоков, для которых выполнена отмена инициализации.
Влияние на среду выполнения
Этот помощник отладки управляемого кода не оказывает никакого влияния на среду CLR.
Выходные данные
Состояние контейнера СОМ текущего потока и состояние, которое пытался применить код.
Настройка
<mdaConfig>
<assistants>
<invalidApartmentStateChange />
</assistants>
</mdaConfig>
Пример
Следующий пример кода демонстрирует ситуацию, которая может активировать данный MDA.
using System.Threading;
namespace ApartmentStateMDA
{
class Program
{
static void Main(string[] args)
{
Thread.CurrentThread.SetApartmentState(ApartmentState.STA);
}
}
}