invalidApartmentStateChange MDA
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);
}
}
}