在我的C#应用​​程序中处理异常的地方在哪里?

时间:2011-11-22 20:35:47

标签: c# .net exception-handling try-catch

所以我最近编写了一个用C#编写的相对复杂的应用程序,它反复执行一系列小任务。当我第一次启动应用程序时,我意识到我输入的很多代码都是重复的,所以我开始将应用程序的大部分逻辑封装到我可以根据需要调用的独立辅助类中。

毋庸置疑,我的应用程序(和代码量)的大小减少了一半。但是当我经历时,我注意到我的应用程序中的其他东西似乎是重复的,看起来可以改进。

现在我的助手类中的大部分方法都是对文件进行HttpWebRequest或执行保存/删除操作。说过我需要处理最终调用无法完成的可能性,或者文件无法保存,因为没有足够的空间,或者其他什么。我遇到的问题是每次调用其中一个方法时我都要继续编写try / catch语句。最重要的是,我必须重新键入错误消息(或最终一个状态消息。我想知道它何时成功)。

所以这里有一个我要输入的内容片段:

  try
  {
     ItemManager.SaveTextPost(myPostItem);
  }
  // Majority of the time there is more than one catch!
  catch
  {
     //^^^Not to mention that I have to handle multiple types of exceptions 
     //in order to log them correctly(more catches..ugh!)
     MessageBox.Show("There was an error saving the post.");
     //Perform logging here as well
  }

到目前为止我得出的结论是:

  • 对我而言,为我的应用程序写这个超过50次是太过分了。 听起来我应该在helper类中包含它 包括全套渔获物。
  • 但我怎么知道结果呢?我也许想回归一个 包含错误/成功消息的字符串。
  • 实际上对于这些类型的方法,它不需要从中调用辅助方法的方法将其包含在try / catch块中。

这种做法是否正确?还有另一种方法吗?我应该在调用方法中使用try / catch吗?由于这种我的第一次拍摄,我真的很想听听处理这种情况的其他人所说的话。

7 个答案:

答案 0 :(得分:1)

AOP这样的

PostSharp库旨在处理与此类似的跨领域问题。

如果所有这些辅助方法都使用相同的样板,请尝试catch - >处理多种类型的异常,然后您可以编写一个方面,并使用适当的属性修饰所有相关方法。

答案 1 :(得分:1)

我认为将try / catch放在你调用的方法中是完全没问题的。您可以通过各种方式将错误/成功代码返回给调用代码。 .NET和c#很好地处理枚举,所以你可以使用ItemManager.SaveTextPost(myPostItem, out errorCode);,其中errorCode是一个枚举值,可以让你知道是否有任何问题发生。它也可以像让方法返回bool一样简单,如果成功则返回true,否则返回false。有很多方法可以解决这个问题,但就我而言,将try / catch放在方法中是最好的做法。

答案 2 :(得分:1)

对于异常处理没有单一的完美规则,所以答案是:它取决于。通常,如果您知道如何处理异常,则应该只捕获异常。在您的示例中,我的第一个问题是,如果应用程序可以在此错误之后继续运行并且仍处于有效状态。如果没有,您应该在记录后重新抛出异常。然后考虑嵌套异常:您可以捕获异常,通过将其嵌套到另一个异常并抛出该异常来添加信息。如果仔细设计异常类和处理程序,则日志记录和显示代码应该比预期的简单得多。但细节显然取决于你的申请。

答案 3 :(得分:1)

如果每个参数都正确,每个文件都可以访问,那么你应该通过检查if块来在你的帮助方法中抛出异常......然后如果需要,在你的帮助方法中实现一些try catch块。捕获时抛出异常。

最后,用try catch块封闭这些辅助方法,但此时,确实捕获异常:

try
{
   ItemManager.SaveTextPost(myPostItem);
   // SaveTextPost can throw some exceptions (that you know)
}
catch (Exception e)
{
   // You know the exceptions that SaveTextPost can return, so threat them 
   // correctly
   if (e is FileNotFoundException)
       MessageBox.Show("The file was not found when saving the post.");
   else if (e is ArgumentNullException)
       MessageBox.Show("The post can't be null to be saved.");
   else
       MessageBox.Show("There was an error saving the post.");
}

最后,您需要处理错误并向用户显示错误消息。您只能决定是否应在辅助方法或调用辅助方法的类中实现MessageBox.Show
就个人而言,我认为帮助方法注定会被任何运行代码的开发人员使用,所以你应该让他决定他想对错误做些什么。这意味着在辅助方法中抛出异常。

答案 4 :(得分:1)

Try / Catch是一个很好的解决方案。一个建议,我喜欢用它来阻止错误的流动:异常捕获:     尝试     {     }     catch(Exception ex)     {         ShowExceptionError(前);     } 然后我将简单地将所有异常抛给单个方法,并让方法处理每个方法。

有点像这样:

private void ShowExceptionError(ex)
{
    string errorMessage = "Type of error:" + ex.GetType().ToString();
    string stackTrace = ex.StackTrace();
    MessageBox.Show(errorMessage + "\n\n" + stackTrace);
}

答案 5 :(得分:1)

所有这些方式都是很好的选择。您不想做的一件事是使用try {} catch {}进行流控制。这意味着这样的事情(再次避免这种情况)

Void SomeMethod()
{
     try
     {
         while(somecondition)
         {
             try
             {
             }
             catch (Exception ex)
             {

             }
          }
     }
     catch (Exception ex)
     {
          .....
     }

相反,你想要进行防御性编码。

答案 6 :(得分:0)

我个人对异常处理的看法是......在有意义的地方添加try {} catch {}

例如,在调用“不可信”代码时,总是使用try catch,即模块或插件。否则,如果您要捕获异常,请确保您可以使用它做一些有意义的事情。如果没有,请允许异常冒泡到可以的位置。

比试图调试应用程序更糟糕的事情,开发人员捕获异常并返回bool。只是说'