假设下面的情况。窗体有一个按钮,单击该按钮即可启动后台工作程序。在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在FormMain.backgroundWorker_RunWorkerCompleted方法中的“抛出新异常()”处,而不是在Application.Run调用时中断。在此基础上,用TargetInvocationException包装真正的异常,并将调用堆栈简化为Program.Main方法,因此无法检查导致异常的代码。
如何防止这种包装?我是不是做错了什么?
从TargetInvocationException提供的调用堆栈来看,有许多调用方法堆叠在一起,对于我对消息循环的基本理解和对线程的基本理解来说,这太多了。
编辑:我知道TargetInvocationException中有InnerException属性,可以通过查看那里来跟踪错误,但这不是问题所在。问题是如何让Visal Studio在用TargetInvocationException包装真正的异常之前停止,这样我就可以使用VS IDE提供的所有那些很好的调试功能。
发布于 2012-05-28 23:04:16
是的,这是一个不幸的副作用,它使RunWorkerCompleted事件在UI线程上运行。由于没有您编写的代码使其运行,因此调试器不能显示任何相关内容,只显示程序中仍然涉及的最后一条语句,即启动消息循环的Application.Run()调用。
您必须通过强制调试器在引发异常时停止来调试它。Debug + Exceptions,勾选CLR异常的抛出复选框。还要注意在没有调试器的情况下运行此命令时的行为,您将看到“财富之轮”对话框。用Application.SetUnhandledExceptionMode()解决这个问题。
https://stackoverflow.com/questions/10785940
复制相似问题