3

次の状況を想定します。フォームには、クリックするとバックグラウンド ワーカーを開始するボタンがあります。RunWorkerCompleted イベント ハンドラーには、未処理の例外をスローするコードがあります。フォームは Application.Run メソッドから開始されます。

public partial class FormMain : Form
{
    public FormMain()
    {
        InitializeComponent();
    }

    private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        throw new Exception();
    }

    private void button_Click(object sender, EventArgs e)
    {
        backgroundWorker.RunWorkerAsync();
    }
}

問題は、FormMain.backgroundWorker_RunWorkerCompleted メソッドの "throw new Exception()" ではなく、Application.Run 呼び出しで Visual Studio が中断することです。その上、実際の例外は TargetInvocationException でラップされ、コール スタックは Program.Main メソッドに削減され、そのために例外を引き起こしたコードを検査できません。

そのラッピングを防ぐ方法は?私は本質的に間違ったことをしていますか?

TargetInvocationException で提供されるコール スタックから判断すると、多くの呼び出しメソッドが積み上げられており、メッセージ ループの基本的な理解とスレッド化のそれほど基本的ではない理解には多すぎます。

編集: TargetInvocationException に InnerException プロパティがあり、そこを見ることでエラーを追跡できることは知っていますが、それは問題ではありません。問題は、TargetInvocationException で実際の例外をラップする前に Visal Studio を停止して、VS IDE が提供する優れたデバッグ機能をすべて使用できるようにする方法です。

4

1 に答える 1

3

はい、これは RunWorkerCompleted イベントを UI スレッドで実行する魔法による残念な副作用です。あなたが書いたコードが実行されていないため、デバッガーは関連するものを表示できませんが、まだ関与しているプログラム内の最後のステートメント、メッセージループを開始した Application.Run() 呼び出しです。

例外がスローされたときにデバッガーを強制的に停止して、これをデバッグする必要があります。[Debug + Exceptions] で、CLR 例外の [Thrown] チェックボックスをオンにします。また、デバッガーなしでこれを実行したときの動作にも注意してください。Wheel Of Fortune ダイアログが表示されます。Application.SetUnhandledExceptionMode() でそれを修正します。

于 2012-05-28T15:04:16.423 に答える