invalidApartmentStateChange MDA

備註

本文專指 .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.ApartmentStateSetApartmentStateTrySetApartmentState 方法。 使用該 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);
        }
    }
}

另請參閱