【问题标题】:Exception handling with background workers后台工作人员的异常处理
【发布时间】:2016-06-18 10:43:26
【问题描述】:

我知道这与问题Background worker exception handling 有点相似,但有点不同。

因此,根据我对后台工作者的理解,当 dowork() 方法中发生异常时,异常将传递给 RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 中的e.Error。 我的问题有几个部分。

1.) 工作是否会在异常发生的行之后停止执行所有其他代码,然后传递给RunWorkerCompleted?是否有必要/最佳实践在 DoWork() 中使用 try/catch 来确保这种行为?

2.) 当从DoWork()RunWorkerCompleted() 方法内部抛出异常时,也会抛出异常。 示例:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    try
    { 
       //Should I be putting code in this as well as getting the exception in `RunWorkerCompleted()`?
       //Or is the already how the background worker works already with out me needing to explicitly put the try/catch?  
    }
    catch (Exception ex)
    {
        throw ex; //is this throwing to the 'RunWorkerCompleted()` or outside the thread to error handling on in the thread where RunWorkerAsync() was called?
    } 
}

private void backgroundowrker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    if (e.Error != null
    {
        throw e.Error; //This throws it back to the thread that called `RunWorkerAsync()` right?
    }
}

【问题讨论】:

  • 旁注,将 throw ex; 更改为 throw;。对于前者,您会丢失整个调用堆栈,这是一种非常糟糕的做法,不幸的是这种做法很常见。
  • 测试时会发生什么?只是在方法backgroundWorker1_DoWork 中抛出一个异常而不捕获它,你观察到了什么?看来您的两个问题都很容易测试并得到答案。
  • @Igor throw; 即使是自定义异常,是否仍然抛出异常?
  • 是的,它基本上会重新抛出你在 catch 块中捕获的异常,但会保持堆栈跟踪的状态。

标签: c#


【解决方案1】:
  1. 在抛出异常后,DoWork 方法中的任何代码都将是无法访问的代码,因此它不会运行,Visual Studio 实际上会警告您这一点。一般来说,使用异常作为流控制是不受欢迎的——相反,我会使用包含错误字段的返回类型,以便您可以显式处理它,但这实际上取决于场景。
  2. RunWorkerCompleted 将在启动 异步方法调用。也就是说,无论哪个线程调用RunWorkerAsync 将是引发异常的那个

我要提醒一下,我已经多年没有使用后台工作程序了——.NET/C# 中较新的异步功能使用起来更加简洁。

【讨论】:

  • 那么我不需要try catch?如果我确实从 DoWork() 中抛出,它会去哪里?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多