17

私は通常長い時間がかかる複雑な計算を実行するC#(.net 3.5 cp、vs2010)のクラスを持っています。1 分後、ContextSwitchDeadlock が検出されたという例外がスローされます。例外は英語以外の言語にローカライズされているため、コピーして貼り付けることはできませんが、意味は次のとおりです。 ¨ CLR モジュールは、コンテキスト COM ... からコンテキスト COM ... に 60 秒間遷移できませんでした。ターゲット コンテキスト/アパートメントを所有するサブプロセスは、おそらく非ポンピング待機を行っているか、Windows システム メッセージをポンピングせずに非常に長時間実行される操作を処理しています。

基本的に、私のアプリケーションはコンピューティングを行っていて、長い間ウィンドウに応答していないようで、ビジュアル スタジオはそれをシャットダウンし、デッドロックの可能性を報告します。

私はいくつかの調査を行おうとしており、2つの解決策を見つけました。

  1. デッドロックを検出するために、Visual Studio デバッガーの一部のオプションを無効にします。デバッグ目的でのみ機能するため、機能しません。

  2. いくつかの DoEvents メソッドを呼び出しますが、それは WPF ではなく Windows フォーム用であり、私は WPF を使用しています。

別のスレッドを作成するという提案もありましたが、私はスレッド化がまったく初めてで、どうすればよいかわかりません。何か提案はありますか?

4

1 に答える 1

39

これは、Managed Debugging Assistant (MDA) からの単なる警告です。あなたのコードは、シングル スレッド アパートメント (STA) スレッドのかなり厳しい要件に違反しています。長期間ブロックすることは許可されていません。警告は十分に現実的であり、UI スレッドをブロックすると簡単にデッドロックが発生する可能性があります。しかし、あなたの場合の説明は簡単です。実際にブロックされたからではなく、コンピューティングがビジーであるため、カタトニックになります。MDA は違いを見分けることができません。

Debug + Exceptions で警告をオフにし、Managed Debugging Assistants ノードを開き、ContextSwitchDeadlock のチェックを外すことができます。

それでも、ユーザーのデスクトップには完全に機能していないウィンドウが表示され、優れたユーザー エクスペリエンスとは言えません。また、他のプログラムがトップレベル ウィンドウにメッセージを送信したときに応答しなくなるなどの副作用が生じる可能性があります。

この問題を実際に解決するには、スレッドを使用する必要があります。BackgroundWorker を見てください。MSDN ライブラリや他の多くの場所で十分に文書化されています。

于 2011-11-12T17:38:11.430 に答える