共用方式為


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 屬性以及 SetApartmentStateTrySetApartmentState 方法。 使用 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);
        }
    }
}

另請參閱