invalidApartmentStateChange MDA

更新 : 2007 年 11 月

invalidApartmentStateChange マネージ デバッグ アシスタント (MDS: Managed Debugging Assistant) は、次の 2 つの問題のいずれかによってアクティブになります。

  • COM によって既に初期化されているスレッドの COM アパートメントの状態が、異なるアパートメント状態に変更されようとしました。

  • スレッドの COM アパートメントの状態が予期せず変更されました。

症状

  • スレッドの COM アパートメントの状態が、要求された状態と異なります。これにより、現在とは異なるスレッド処理モデルの COM コンポーネントで、プロキシが使用されることがあります。そのため、アパートメント間マーシャリングがセットアップされていないインターフェイスを通じて COM オブジェクトが呼び出されるときに、InvalidCastException がスローされる場合があります。

  • スレッドの COM アパートメントの状態が、想定と異なります。これにより、ランタイム呼び出し可能ラッパー (RCW) で呼び出しが行われたときに、RPC_E_WRONG_THREAD 値が HRESULT で COMException が発生したり、InvalidCastException が発生したりすることがあります。また、一部のシングルスレッド COM コンポーネントは、複数のスレッドから同時にアクセスされてしまうこともあり、その結果、破損やデータの損失が発生することもあります。

原因

  • スレッドは既に初期化されていて、別の COM アパートメント状態になっています。スレッドのアパートメント状態は、明示的にも暗黙的にも設定できることに注意してください。明示的な操作には、Thread.ApartmentState プロパティ、SetApartmentState メソッド、および TrySetApartmentState メソッドが含まれます。Start メソッドを使用して作成されたスレッドは、スレッドが開始する前に SetApartmentState が呼び出されない限り、暗黙的に MTA に設定されます。また、アプリケーションのメイン スレッドは、STAThreadAttribute 属性がメイン スレッドで指定されていない限り、暗黙的に MTA に初期化されます。

  • 異なる同時実行モデルの CoUninitialize メソッド (または CoInitializeEx メソッド) が、スレッドで呼び出されました。

解決策

スレッドの実行開始前に、スレッドのアパートメント状態を設定します。または、アプリケーションのメイン スレッドに、STAThreadAttribute 属性または MTAThreadAttribute 属性を適用します。

2 番目の原因の場合は、CoUninitialize メソッドを呼び出すコードを変更して、スレッドが終了するまで呼び出しを遅延させ、スレッドによって使用中のままとなっている RCW とその基本となる COM コンポーネントがないようにすることが理想的です。ただし、CoUninitialize メソッドを呼び出すコードを変更できない場合、この方法で初期化されていないスレッドから RCW を使用しないでください。

ランタイムへの影響

この MDA は、CLR への影響はありません。

出力

現在のスレッドの COM アパートメント状態、およびコードに適用しようとした状態です。

構成

<mdaConfig>
  <assistants>
    <invalidApartmentStateChange />
  </assistants>
</mdaConfig>

使用例

この MDA をアクティブにできる状況のコード例を次に示します。

using System.Threading;
namespace ApartmentStateMDA
{
    class Program
    {
        static void Main(string[] args)
        {
            Thread.CurrentThread.SetApartmentState(ApartmentState.STA);
        }
    }
}

参照

概念

マネージ デバッグ アシスタントによるエラーの診断

相互運用マーシャリングの概要

参照

MarshalAsAttribute