【问题标题】:TargetInvocationException from BackgroundWorker_RunWorkerCompleted来自 BackgroundWorker_RunWorkerCompleted 的 TargetInvocationException
【发布时间】:2012-05-28 14:04:44
【问题描述】:

假设以下情况。表单有一个按钮,单击该按钮可启动后台工作人员。在 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 调用处中断,而不是在 FormMain.backgroundWorker_RunWorkerCompleted 方法中的“throw new Exception()”处中断。最重要的是,真正的异常被 TargetInvocationException 包裹,调用堆栈被缩减为 Program.Main 方法,因此无法检查导致异常的代码。

如何防止这种包装?我做错了什么吗?

从 TargetInvocationException 提供的调用堆栈来看,调用方法堆积如山,对于我对消息循环的基本理解和对线程的不太基本的理解来说太多了。

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

【问题讨论】:

  • TargetInvocationException 的情况下,InnerException 属性包含基础异常。
  • @Damith 我知道,这不是我要问的。我已编辑问题以防止出现此类答案。

标签: .net backgroundworker targetinvocationexception


【解决方案1】:

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

您必须通过在抛出异常时强制调试器停止来进行调试。 Debug + Exceptions,勾选 CLR exceptions 的 Throw 复选框。还要注意当你在没有调试器的情况下运行它时的行为,你会得到命运之轮对话框。使用 Application.SetUnhandledExceptionMode() 修复该问题。

【讨论】:

  • 捕获所有抛出的异常有一个令人讨厌的副作用,即在每个异常(包括已处理的异常)上停止 IDE。我想仍然可以发送一条 windows 消息并在主线程的某个地方处理它。
  • 仅在异常情况下使用异常。您已经有一个“某处”并且您已经在主线程上。无需发送消息,在 RunWorkerCompleted 事件处理程序中处理。
  • 事情是,我正在从事一个在后台工作人员完成后必须完成非平凡逻辑的项目。当像将重复键放入字典这样微不足道的事情引发异常时,挖掘内部异常堆栈跟踪真的很烦人。别担心我不练习“异常驱动设计”
  • 我用 PostMessage、pinvoke 和消息过滤做了一些实验。它无需反思即可完成工作。权衡是 pinvoke 引入了一些应该保持在 C# 级别以下的低级内容,例如作为窗口句柄的指针。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-10-22
  • 1970-01-01
  • 1970-01-01
  • 2014-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多