ContextSwitchDeadlolck


Visual Studio 2005でデバッグ時に、ブレークポイント等で実行を止めたまま、一定の時間(メッセージからすると60秒)が経過すると発生する。

ContextSwitchDeadlock が検出されました。
Message: CLR は、COM コンテキスト 0x1b0b70 から COM コンテキスト 0x1b0ce0 へ 60 秒で移行できませんでした。ターゲット コンテキストおよびアパートメントを所有するスレッドが、ポンプしない待機を行っているか、Windows のメッセージを表示しないで非常に長い実行操作を処理しているかのどちらかです。この状態は通常、パフォーマンスを低下させたり、アプリケーションが応答していない状態および増え続けるメモリ使用を導く可能性があります。この問題を回避するには、すべての Single Thread Apartment (STA) のスレッドが、CoWaitForMultipleHandles のようなポンプする待機プリミティブを使用するか、長い実行操作中に定期的にメッセージをポンプしなければなりません。

以前はブレークさせたままでどんだけ待たせても、こんな例外出ていなかったはずなのだが。

追記:原因が判明した。


私はこのスクリーンショット中のオプション、"アンマネージコードデバッグを有効にする"のチェックを外したのをすっかり忘れていたのだが、これが今回のトラブルの原因だったようだ。
そもそも、C#デバッグしかしないので、アンマネジコードのデバッグは不要だと、思い込みでこのオプションを外したのだが、その結果、マネジコードをブレークポイントで止めても、アンマネジコードは止まらない = アンマネジスレッドは止まらない、という状況を引き起こしていたのである。(実際に、このオプションをチェックしたところ、60秒を超えても同例外は発生しなくなった)

問題が解決したのは、.NET Debugging Blogにこの事が詳しく言及してあったからである。

Native threads still run at a managed breakpoint.
Why you sometimes get a bogus ContextSwitchDeadLock MDA under the debugger
- Mike Stall's .NET Debugging Blog

アプリケーションが重い場合、余計な機能は止めるべし、という基本戦略が却って仇になったようだが、それにしても、これってFAQじゃないのだろうか。混在コードではない、C#単体でデバッグするのだから、アンマネジデバッグは不要だよね、と思ってこの機能をオフにする人は私だけだろうか?
マネジコードだけ扱っているつもりでも、どこかで、アンマネジなコードが動作していることはある程度.NETの知識があれば理解できるが、デバッグのオプションにまで影響するのであれば、そもそもこのオプションのOn/Offは不要だとも思えてくる。