后台工作线程异常处理

本文关键字:异常处理 线程 工作 后台 | 更新日期: 2023-09-27 18:32:09

我正在使用以下组件:

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

我正在使用后台工作程序调用库方法。库引发异常,但永远不会调用 RunWorkerDone 处理程序。

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

是否误解了 RunWorkerCompleteEventArgs.Error 属性?不是因为获得被后台工作者捕获的异常吗?

代码示例:

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){ }
}

后台工作线程异常处理

这是 BackgroundWorker 的正确模式。

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

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

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


出于兴趣:

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

在控制台应用中,使用默认的同步上下文,这会RunWorkerCompleted封送到线程池线程上。这意味着您可以阻止Main线程,并且已完成的处理程序仍将运行。