BackgroundWorker的DoWork方法中异常无法传递到RunWorkedCompleted方法的解决方法

在使用C#的BackgroundWorker时需要在UI界面上显示DoWork中发生的异常,但怎么调试都无法跳转到界面上,异常也不会传递到RunWorkerCompleted方法中(e.Error为空)。在网上搜了很多类似的问题都没有找到答案(搜索方法不对,还是运气不好?),幸好在CSDN上搜到了一个相似的问题(如何统一处理BackgroundWork产生的异常),看到里面说使用“开始执行(不调试)”依然无法传递出异常,才想到可能是调试的问题,改用“开始执行(不调试)”(调试菜单,或CTRL+F5)成功解决这个问题。眼睛疼,睡觉。

 DoWork方法执行时发生异常并中断程序运行,无法通过e.Error获取异常:

 

界面上显示错误:

补充:上述的解决方法在正式执行使用程序时还是发生了问题,没有将异常传递到Completed函数中。后来使用了一个稍微麻烦点的方法处理:在DoWork中使用try-catch对异常进行捕获,而不通过系统自动抛出(如上面所说,如果自己不进行捕获,调试时异常无法进入Completed函数处理),然后将捕获的异常赋值给e.Result返回给Completed函数进行处理,这样可以在调试模式下跟踪异常。为了便于使用,我自定义了一个额外的类WorkResult来表示DoWork返回的结果,其中包括一个Exception类型的属性Error用于保存捕获的异常和一个string类型(也可以是object类型)的属性Result用于保存DoWork需要返回的结果,最后在DoWork结束时将这个WorkResult的实例赋值给e.Result,这样就可以在RunWorkerCompleted函数中通过e.Result获取DoWork的操作结果和异常。部分代码如下。

定义WorkResult类并在DoWork函数中将异常和操作结果存入WorkResult实例中:

class WorkResult
{
      public OperationType Operation { get; set; }
      public Exception Error { get; set; }
      public string Result { get; set; }
}
private void DoWork(object sender, DoWorkEventArgs e)
{
      WorkResult result = new WorkResult();//自定义返回结果,包括操作类型和WebService执行的结果
      Exception ex = null;
      
       //DoWork需要处理的工作          
      ..........

       if (ex != null)
       {
            result.Error = ex;
       }
       e.Result = result;
 }

在RunWorkerCompleted函数中处理异常(通知用户发生错误或者其他操作):

private void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    //取得DoWork操作结果
    WorkResult result = e.Result as WorkResult;
    if (result == null)
    {
        MessageBox.Show("发生错误!异步操作返回结果不是WorkResult类型。");
        return;
    }
    
    if (result.Error != null)
    {
        //如果异步操作过程中发生异常,那么在这里处理
      ......
    }
    else
     {
          //对结果进行处理
       ......
     }
}


如果大家对于这个问题有其他的解决方法还请在评论区贴出来,以便于遇到这个问题但不知道怎么解决的朋友使用,谢谢。

 

posted @ 2017-04-28 22:59  夏虫EG  阅读(3845)  评论(2编辑  收藏  举报