BackgroundWorker 异常处理

Posted

技术标签:

【中文标题】BackgroundWorker 异常处理【英文标题】:BackgroundWorker exception handling 【发布时间】:2012-05-05 04:28:12 【问题描述】:

我正在使用以下组件:

一个库(引发异常) 一个测试控制台来测试我的日志记录 企业库异常处理应用程序块 企业库日志记录应用程序块

我正在使用后台工作程序调用库方法。库引发异常,但从未调用 RunWorkerCompleted 处理程序。

捕获异常的唯一方法是用 try/catch 块包围我的 DoWork 处理程序代码。

是否误解了 RunWorkerCompletedEventArgs.Error 属性?不是为了获取被BackgroundWorker捕获的异常吗?

代码示例:

static BackgroundWorker w = new BackgroundWorker();

w.DoWork += new DoWorkEventHandler(w_DoWork);
w.RunWorkerCompleted += 
   new RunWorkerCompletedEventHandler(w_RunWorkerCompleted);
w.RunWorkerAsync();



static void w_DoWork(object sender, DoWorkEventArgs e)

   MyClass m  = new MyClass();
   w.result = m.Compute();


static void w_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)

   if (e.Error != null)
   
      HandleException(e.Error);
   

   /* result related code */




static void HandleException(Exception e)

   ExceptionPolicy.HandleException(e, "MyPolicy");

以上示例导致我的控制台应用程序终止。 vs2010 输出绝对不写任何东西(只有默认输出)。

那么问题出在哪里?

//编辑:这个 sn-p 用于捕获库的异常。

static void w_DoWork(object sender, DoWorkEventArgs e)

   try
   
      MyClass m  = new MyClass();
      w.result = m.Compute();
   catch(Exception e) 


【问题讨论】:

你在主线程上有什么东西阻止它结束吗?有点像一段时间(真的)? 您是否 100% 确定 RunWorkerCompleted 永远不会被调用?这是一个证明这应该有效的问题...***.com/questions/1044460/… 你不能调试看看会发生什么? HandleException() 返回什么? 我没有一段时间是真的或类似的东西。只是一个 Main(string[] args) 和 bw 的静态处理程序。是的,永远不会调用 RunWorkerCompleted。调试器既不会在那里停止,也不会在处理程序开始时执行任何操作(File.Create、Debug.WriteLine 等)。 @Reniuz - 我确定我记得 C# IDE 有断点! w_RunWorkerCompleted 第一行的排水沟中的红色斑点非常有用。 【参考方案1】:

这是 BackgroundWorker 的正确模式。

我怀疑问题在于您的 Main 方法在 BW 完成之前退出。

RunWorkerAsync 将立即返回,如果您没有在Main 中等待,那么您的进程将结束,甚至可能在 BW 开始之前,更不用说完成了。

尝试在Main 方法的末尾添加Console.ReadLine


出于兴趣:

BW 在控制台应用程序和 Windows 应用程序中的行为不同。如果您使用 WinForms 或 WPF 应用程序,您的 UI 线程上将有一个派生的 SynchronizationContext,BW 会将 RunWorkerCompleted 编组回 UI 线程并在那里运行它。这是 BW 的主要优势之一。

在控制台应用程序中,使用默认的 SynchronizationContext 并将RunWorkerCompleted 编组到线程池线程上。这意味着您可以阻塞 Main 线程,并且完成的处理程序仍将运行。

【讨论】:

我使用了一个控制台应用程序,因为它是测试库的最快方法。在 WPF 应用程序中展示我的结果需要更多时间。 @MartinJames 我大部分时间都在编写控制台应用程序,这些应用程序在服务器上进行调度和运行。对于这种情况,UI 既无用也不可行。在控制台应用程序中进行简单测试也更容易一些;只需做一些简单的事情并查看结果即可减少开销。 好的!我收回企鹅的东西。不要再打我了:)

以上是关于BackgroundWorker 异常处理的主要内容,如果未能解决你的问题,请参考以下文章

如何在点击触发的backgroundWorker中添加一段代码?

c# BackGroundWorker 多线程操作的小例子

C#中用Backgroundworker调用UI的textbox控件,对其赋值,有时会抛出异常。

c# winForm开发的一个异常问题,异常描述是:"调用的目标发生了异常问题"

使用后台线程BackgroundWorker处理任务的总结

Koa异常处理说明