BackgroundWorker_RunWorkerCompleted中的TargetInvocationException

时间:2012-05-28 14:04:44

标签: .net backgroundworker targetinvocationexception

假设以下情况。表单上有一个按钮,单击该按钮即可启动后台工作程序。在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();
    }
}

问题是Visual Studio在Application.Run调用时中断了#34;抛出新的异常()"在FormMain.backgroundWorker_RunWorkerCompleted方法中。最重要的是,使用TargetInvocationException包装真正的异常,并将调用堆栈简化为Program.Main方法,导致异常的代码因此无法检查。

如何防止包裹?我在做一些内在错误的事情吗?

从TargetInvocationException提供的调用堆栈判断,有很多调用方法堆积起来,对于我对消息循环的基本理解以及对线程的不那么基本的理解太过分了。

编辑: 我知道TargetInvocationException中有InnerException属性,并且可以通过查看那里来查找错误,但这不是问题。问题是如何在使用TargetInvocationException包装真正的异常之前使Visal Studio停止,这样我就可以使用VS IDE提供的所有那些不错的调试功能。

1 个答案:

答案 0 :(得分:3)

是的,这是使得RunWorkerCompleted事件在UI线程上运行的魔力的不幸副作用。没有编写的代码使其运行,因此调试器无法显示任何相关内容,但程序中仍然涉及的最后一个语句,即启动消息循环的Application.Run()调用。

您必须通过强制调试器在抛出异常时停止来调试它。 Debug + Exceptions,勾选CLR异常的Thrown复选框。还要注意在没有调试器的情况下运行它时的行为,你将获得Wheel of Fortune对话框。使用Application.SetUnhandledExceptionMode()修复它。