invalidApartmentStateChange MDA
注意
本文專屬於 .NET Framework。 它不適用於較新的 .NET 實作,包括 .NET 6 和更新版本。
invalidApartmentStateChange
Managed 偵錯助理 (MDA) 是由下列兩個問題之一所啟動:
嘗試變更執行緒的 COM Apartment 狀態,該執行緒已被 COM 初始化成不同的 Apartment 狀態。
未預期的執行緒 COM Apartment 狀態變更。
徵兆
執行緒的 COM Apartment 狀態不是原來要求的。 這可能會導致 Proxy 用於執行緒模型和目前執行緒模型不同的 COM 元件。 如此一來,透過未針對跨 Apartment 封送處理設定的介面呼叫 COM 物件時,可能會擲 InvalidCastException 回 。
執行緒的 COM Apartment 狀態與預期的不同。 在執行階段可呼叫包裝函式 (RCW) 上進行呼叫時,這會造成 COMException 具有 RPC_E_WRONG_THREAD 的 HRESULT 以及 InvalidCastException。 這也會造成多個執行緒同時存取某些單一執行緒的 COM 元件,導致損毀或資料遺失。
原因
執行緒先前已初始化成不同的 COM Apartment 狀態。 請注意,可以明確或隱含方式設定執行緒的 Apartment 狀態。 明確的作業包括 Thread.ApartmentState 屬性以及 SetApartmentState 和 TrySetApartmentState 方法。 使用 Start 方法建立的執行緒,會以隱含方式設成 MTA,除非啟動執行緒之前呼叫 SetApartmentState。 應用程式的主執行緒也會以隱含方式初始化為 MTA,除非在 Main 方法上指定 STAThreadAttribute 屬性。
在執行緒上呼叫具有不同並行模型的
CoUninitialize
方法 (或CoInitializeEx
方法)。
解決方法
請先設定執行緒的 Apartment 狀態再開始執行,或將 STAThreadAttribute 屬性或 MTAThreadAttribute 屬性套用到應用程式的 Main 方法。
第二個原因,在理想情況下,應該修改呼叫 CoUninitialize
方法的程式碼以延遲呼叫,直到執行緒即將終止且沒有任何 RCW 為止,執行緒仍繼續使用它們的基礎 COM 元件。 不過,如果不可能修改呼叫 CoUninitialize
方法的程式碼,則不應從未以此方式初始化的執行緒中使用任何 RCW。
對執行階段的影響
此 MDA 對 CLR 沒有影響。
輸出
目前執行緒的 COM Apartment 狀態和程式碼之前嘗試套用的狀態。
組態
<mdaConfig>
<assistants>
<invalidApartmentStateChange />
</assistants>
</mdaConfig>
範例
下列程式碼範例示範可以啟動此 MDA 的情況。
using System.Threading;
namespace ApartmentStateMDA
{
class Program
{
static void Main(string[] args)
{
Thread.CurrentThread.SetApartmentState(ApartmentState.STA);
}
}
}