4

我有一个复杂的程序,它遍历一堆输入文件进行大量解析和计算,然后输出其他几个文件。

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”,但我真的看不出有任何其他方法可以做到这一点。

4

5 回答 5

3

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

于 2012-07-16T15:45:20.813 回答
2

就个人而言,我认为这没有什么问题。您已经清楚地考虑了问题并有合适的解决方案。每当有人在软件开发中说“从不……”时,通常情况正好相反。我想这就是为什么其他人会说“最好……”和“通常……”之类的话。:)

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

于 2012-07-16T15:44:41.180 回答
2

在我看来,这是一个非常合理的案例,捕获 Exception 是有意义的,因为它完成了在问题空间中需要的东西。我对诸如“永远不要这样做,总是那样做......”这样的通用规则非常谨慎,这些规则中的一点灵活性和常识肯定会对我有所帮助。我认为你的代码很好。

于 2012-07-16T15:46:33.353 回答
1

一般来说,我不喜欢抛出异常(除非应用程序处理被迫停止),因为它们会导致性能开销。这篇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();
}
于 2012-07-16T15:52:04.700 回答
1

对于您的应用程序来说,满足解决您要解决的问题的要求是一种很好的形式,如果按照您的方式进行操作是方便且功能正确的,那么就这样做。

绝对忽略上下文,并且没有最佳实践之类的东西——只有“这段时间适合我们上下文的最佳实践”。

于 2012-07-16T15:52:04.770 回答