我正在使用以下组件:
>一个库(引发异常)
>测试控制台来测试我的日志记录
>企业库异常处理应用程序块
>企业库日志应用程序块
我正在使用backgroundworker调用库方法.库抛出异常,但RunWorkerCompleted处理程序从不被调用.
捕获异常的唯一方法是使用try / catch块来包围我的DoWork处理程序代码.
是否误会了RunWorkerCompletedEventArgs.Error属性?是不是得到了BackgroundWorker被抓到的异常?
Codesample:
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的正确模式.
RunWorkerAsync将立即返回,如果您不在Main中等待,那么您的进程即将结束,甚至在BW开始之前也不会完成.
尝试在主方法的末尾添加一个Console.ReadLine.
不感兴趣:
控制台应用程序和Windows应用程序中BW的行为不同.如果您使用WinForms或WPF应用程序,您的UI线程上将会派生一个派生的SynchronizationContext,而BW会将RunWorkerCompleted组织回UI线程并在其中运行.这是BW的主要好处之一.
在控制台应用程序中,使用默认的SynchronizationContext,并将RunWorkerCompleted编组到线程池线程上.这意味着您可以阻止主线程,并且完成的处理程序仍将运行.