備註
本文專指 .NET 框架。 此規定不適用於較新的 .NET 實作,包括 .NET 6 及更新版本。
invalidApartmentStateChange管理除錯助理(MDS)會因以下兩種問題之一而啟動:
嘗試將已由 COM 初始化的執行緒的 COM 公寓狀態變更為不同的公寓狀態。
討論串的 COM 公寓狀態會突然改變。
Symptoms
一個討論串的COM公寓狀態並不是被要求的。 這可能導致代理被用於執行緒模型與目前不同的 COM 元件。 這可能導致在透過未設定跨公寓封裝的介面呼叫 COM 物件時拋出 。InvalidCastException
討論串中 COM 公寓的狀態與預期不同。 這可能導致 HRESULT COMException 為 RPC_E_WRONG_THREAD,以及在執行時可呼叫包裝器(RCW)呼叫時產生 AInvalidCastException。 這也可能導致部分單執行緒的 COM 元件同時被多個執行緒存取,進而導致資料損壞或遺失。
原因
該執行緒之前被初始化到另一個 COM 公寓州。 請注意,執行緒的公寓狀態可以是明確設定的,也可以是隱含的。 明確的操作包括屬性 Thread.ApartmentState 與 SetApartmentState 和 TrySetApartmentState 方法。 使用該 Start 方法建立的執行緒會隱含地設為 , MTA 除非 SetApartmentState 在啟動執行緒前被呼叫。 應用程式的主執行緒也會隱含初始化為 MTA ,除非主方法中指定屬性 STAThreadAttribute 。
CoUninitialize執行緒中呼叫的是具有不同並發模型的方法(或方法CoInitializeEx)。
Resolution
在執行緒開始執行前設定 apartment 狀態,或將屬性MTAThreadAttribute或屬性套用STAThreadAttribute到應用程式的主要方法。
針對第二個原因,理想情況下,呼叫該方法的程式碼 CoUninitialize 應該被修改,延遲呼叫,直到執行緒即將終止且執行緒中沒有 RCW 及其底層 COM 元件仍在使用。 然而,如果無法修改呼叫該 CoUninitialize 方法的程式碼,則不應從未以這種方式初始化的執行緒中使用任何 RCW。
對運行時間的影響
此 MDA 對 CLR 沒有影響。
Output
目前執行緒的 COM 公寓狀態,以及程式碼嘗試套用的狀態。
Configuration
<mdaConfig>
<assistants>
<invalidApartmentStateChange />
</assistants>
</mdaConfig>
範例
以下程式碼範例展示了一種可能啟動此 MDA 的情況。
using System.Threading;
namespace ApartmentStateMDA
{
class Program
{
static void Main(string[] args)
{
Thread.CurrentThread.SetApartmentState(ApartmentState.STA);
}
}
}