BackgroundWorker和异常

5

根据MSDN文档所述:

如果操作引发了您的代码未处理的异常,BackgroundWorker会捕获该异常并将其传递到RunWorkerCompleted事件处理程序中,在那里它作为System.ComponentModel.RunWorkerCompletedEventArgs的Error属性暴露出来。

但是当我尝试时:

_workers[i].DoWork += (s, args) =>
{
    throw new Exception("Error!");
};

我收到了“未处理异常错误”的信息... 代码似乎不会进入“RunWorkerCompleted”方法。那么错误应该如何处理?

更新

我已经设置了简单的处理程序。

_workers[i].DoWork += (s, args) =>
{
    throw new Exception("Error!");
}
...
_workers[i].RunWorkerCompleted += (s, args) =>
{
    if (args.Error != null) {
        string dummy = args.Error.Message;
    }
    ...
};

代码永远不会离开DoWork函数。


你有一个RunWorkerCompleted处理程序吗? - Mitch Wheat
2
你尝试过不使用调试器运行代码吗? - Stefan P.
刚刚完成了,代码确实进入了“RunWorkComplete”处理程序,只是似乎一直在那里“循环”?请参见http://screenr.com/eCF。由于我无法使用VS调试,所以我不知道它为什么会一直循环……我只添加了一个任务。 - Jiew Meng
3个回答

3

如果抛出的异常经过用户框架但未被用户代码捕获,则被视为“用户未处理”。

所以我认为有3种可能性:

  • 这是一个首次机会异常 - 因此,如果按F5,则异常将正常传播。
  • 在异常助手中点击“编辑代码”。然后进行一些编辑和继续操作以解决问题。
  • 转到Debug->Exceptions并取消选择“用户未处理”列。

2
如果你正在通过调试器运行程序,Visual Studio 将会在 BackgroundWorker.DoWork 事件处理程序中遇到异常时停止执行,而不是像非调试模式下那样默默地将异常传递给 RunWorkerCompleted 事件。
1)你可以按 F5 继续执行以跟踪异常(正如 RoadWarrior 所提到的)。
2)如果这太烦人了,对于 DoWork 不要使用委托/lambda,而是使用命名方法并用 [DebuggerStepThrough] 属性修饰。这将让调试器忽略该方法并且不会在异常时停止,因此你可以查看 Backgroundworker 的“正常”行为。
参见:Visual Studio 2008 Debugging - Skipping code

你能否解释一下为什么我的Visual Studio没有在DoWork事件中停止抛出的异常,就像你的(1)所说的那样?我希望有些设置。 - PandaWood

0
昨天我在BackgroundWorker中完成了异常处理。在Worker的DoWork处理程序中,我没有添加任何throw。如果发生异常,您将能够在RunWorkerCompleted中获取它而不抛出它。只要不要忘记在异常发生时取消您的Worker即可。

我以为当你抛出异常时,执行会立即结束?所以我不能将 Cancel = true 设置给我的工作线程吗? - Jiew Meng

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接