当失败的原因不重要时捕获System.Exception是否是好的形式?

时间:2012-07-16 15:40:48

标签: c# .net exception-handling

我有一个复杂的程序,迭代一堆输入文件做了很多解析和计算,然后输出其他几个文件。

void ParseFiles(string[] files, ProcessingDescription description) {
  foreach(string file in files) {
    try {
      DoComplicatedProcessing(file, description);
    }
    catch(Exception e) {
      LogFailure(file, e);
    }
  }
  DisplayResult();
}

我在这种情况下捕获System.Exception的原因是这可能由于多种原因而失败,解析/计算中的错误,输入文件中的非法值,权限问题甚至是内存不足错误我假设所有必要的数据都适合记忆,结果证明是假的。

但最后我不在乎为什么失败了。如果程序针对特定文件失败,我希望它记录该失败并继续下一个文件。

在会话结束时,用户可能会回来查看哪些文件失败以及抛出了什么错误消息,确保在许多情况下错误消息可能对用户没有帮助,但它比程序崩溃的第一个坏文件更好

我一直听到“永远不会捕获System.Exception”但我真的看不到任何其他方法。

5 个答案:

答案 0 :(得分:3)

您应该只捕获可以处理的异常。在这种情况下,您可以处理任何异常,因此此代码没有任何问题。

答案 1 :(得分:2)

就个人而言,我没有看到任何错误。你已经清楚地想到了这个问题并找到了合适的解决方案。每当有人在软件开发中说“从不...”时,通常情况就是如此。我猜这就是为什么其他人会说“最好的做法......”和“通常......”。 :)

如果您意识到通过捕获Exception,您将失去异常的粒度,并且您可能会遇到奇怪的边缘情况(内存等),那么您是否承担风险取决于您。

答案 2 :(得分:2)

在我看来,这是一个非常合理的案例,其中捕获异常是有道理的,因为它可以在你的问题空间中实现所需要的。我对“从不这样做,永远这样做......”这样的普遍规则非常谨慎。这些规则中的一点灵活性和常识确实对我有所帮助。我认为你的代码很好。

答案 3 :(得分:1)

通常,我不想抛出异常(除非强制停止应用程序处理),因为它们会导致性能开销。 This MSDN文章提供了一个很好的概述。

根据处理的复杂程度以及由于您只想记录故障,我会评估在可能的情况下添加更多“健全性检查”。像这样:

void ParseFiles(string[] files, ProcessingDescription description) {
  foreach(string file in files) {
    if(!file.IsValid()) { //uses an extension method
      LogFailure(file, "Your Message"); //use the appropriate API
      continue;
    }

    try {    
      DoComplicatedProcessing(file, description);
    }
    catch(Exception e) {
      LogFailure(file, e);
    }
  }
  DisplayResult();
}

答案 4 :(得分:1)

对于您的应用程序来说,满足解决您要解决的问题的要求是一种很好的形式,如果以您的方式执行它是有利的和功能正确的,那就去做吧。

绝对无视上下文,没有最佳实践这样的东西 - 只有“这段时间的最佳实践才适合我们的背景。”