BackgroundWorker 异常处理

10

我正在使用以下组件:

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

我正在使用BackgroundWorker调用库方法。库会抛出异常,但是RunWorkerCompleted处理程序从未被调用。

唯一捕获异常的方法是在DoWork处理程序代码周围加上try/catch块。

我是否误解了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输出根本没有写任何东西(仅默认输出)。

那么问题出在哪里?

//编辑:此片段适用于捕获库的异常。

static void w_DoWork(object sender, DoWorkEventArgs e)
{
   try
   {
      MyClass m  = new MyClass();
      w.result = m.Compute();
   }catch(Exception e){ }

}

1
你的主线程上有什么东西阻止它结束吗?比如 while(true) 这样的东西? - dcarneiro
1
你不能调试一下看看发生了什么吗?HandleException() 返回了什么? - Renatas M.
我没有while true或类似的东西。只有一个Main(string[] args)和bw的静态处理程序。是的,RunWorkerCompleted从未被调用。无论是调试器停在那里还是处理程序开头的任何操作都没有执行(File.Create、Debug.WriteLine等)。 - csteinmueller
@Reniuz - 我确定C# IDE有断点!在w_RunWorkerCompleted的第一行中的红色斑点会非常有用。 - Martin James
@csteinmueller - 然后放点东西进去!一个 Sleep(10000) 循环就可以了。 - Martin James
显示剩余3条评论
1个回答

7

这是BackgroundWorker的正确模式。

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

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

试着在您的Main方法末尾添加一个Console.ReadLine


有趣的是:

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

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


我选择使用控制台应用程序进行测试,因为这是最快的方式。使用WPF应用程序展示结果需要更多的时间。 - csteinmueller
7
@MartinJames 我花费大量时间编写可在服务器上安排和运行的控制台应用程序。对于这样的情况,UI既不实用也不可行。在控制台应用程序中进行简单测试也相对容易;仅需较少的开销即可完成简单操作并查看结果。 - Servy
1
好的!我收回企鹅的话题。请别再打我 :) - Martin James

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