【问题标题】:Wrap every method in try-catch or specific part of code将每个方法包装在 try-catch 或代码的特定部分中
【发布时间】:2015-09-04 09:27:38
【问题描述】:

我的高级同事告诉我将每个方法都包装在一个 try-catch 块中,这样他们就可以跟踪异常发生的位置,从而帮助更快地调试问题。将每个方法包装在 Try Catch 中是否更好,例如:

Public int foo()
{
   try
   {
       //do something
   }catch(Exeception ex)
   {
       //do something with ex
   }
}

或者在我认为可能发生的地方捕获异常更好?例如。对数组做某事可能会导致IndexOutOfRangeException 发生。

//wrap this in try catch
    int[] array = new int[3];

                array[0] = 1;
                array[1] = 2;
                array[2] = 3;
                array[3] = 4;

谢谢。

【问题讨论】:

  • "例如,对数组做某事可能会导致 IndexOutOfRangeException 发生。" - 仅当您有错误时。不要试图捕获由错误引起的特定异常 - 你希望它们失败,被记录,然后得到修复。
  • 不,您绝对不想用 try/catch 块包装每个方法调用。 “这样他们就可以跟踪异常发生的位置” - 这就是堆栈跟踪的用途......
  • 谢谢乔恩,但你能不能稍微扩展一下“你希望他们失败,被记录,然后得到修复。”如何在不通过 try catch 捕获它们的情况下记录它们?
  • 您在顶级 try/catch 中捕获它们,用于整个程序(或请求,或用户操作,或其他任何内容)。但是你不要用 try/catch 乱扔你的整个代码库。
  • 尝试了解您的前辈并亲自检查的要点。

标签: c# try-catch


【解决方案1】:

try 块包含可能导致异常的受保护代码。该块一直执行,直到抛出异常或成功完成。

你可以去How often should I use try and catch看看

捕获异常的基本经验法则是当且仅当您有一种有意义的处理方式时才捕获异常。

如果您只想记录异常并将其扔到堆栈中,请不要捕获异常。它没有任何意义,而且代码混乱。

如果您预计代码的特定部分会失败,并且您有一个回退方法,请务必捕获异常。

当然,您总是遇到需要使用 try/catch 块的已检查异常的情况,在这种情况下您别无选择。即使有已检查的异常,也要确保正确记录并尽可能干净地处理。

【讨论】:

  • 谢谢,你能在“当你期待失败时”稍微扩展一下。
  • 例如,您尝试使用主 SMTP 服务器发送电子邮件,由于超时而引发异常,因此您捕获异常并尝试使用备用备用 SMTP 服务器。
  • @Mohit “如果您只想记录异常并将其扔到堆栈中,请不要捕获异常”- 但是如果您想记录每个异常怎么办?这就是我现在要处理的问题,我需要记录所有内容,但不确定如果我不将它包装在 try catch 中,尤其是因为有很多线程,这意味着它们不会被抛出主线程。
  • 但是,如果我将它捕获并将其扔到堆栈中,最终我的父函数会将其记录在日志文件中。那值得做吗?目前我没有在每个方法中重新抛出和记录异常。所以没有通知用户查看日志,因为错误发生在嵌套函数调用中。
【解决方案2】:

最好在代码的关键部分使用它,然后:

[STAThread]
static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
    AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
    ServerForm form = new ServerForm();
    Application.Run(form);
}
static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
    MessageBox.Show(e.Exception.Message, Program.Name);
}

static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
    MessageBox.Show((e.ExceptionObject as Exception).Message, Program.Name);
}

只是在未处理的异常情况下

【讨论】:

  • 感谢您的意见
【解决方案3】:

使用 Try catch 块没有问题,因为它没有开销(除非你在任何地方都添加它,这可能包括可读性开销),而当没有抛出异常时,通常会为 catch 和 finally 块添加额外的 IL行为上几乎没有区别。

但是,如果您的代码确实引发了异常,这就是您遇到轻微性能问题的地方,因为在这种情况下必须创建异常,必须放置堆栈爬网标记,并且如果处理了异常并访问了它的 StackTrace 属性,则堆栈步行发生。因此,始终将代码包装在 try catch 块中可能不是一个好主意,或者您可以将其放在父级别,然后检查堆栈跟踪

【讨论】:

  • 如果每行真实代码都被 8 行 try/catch 包围,那么可读性会产生巨大的开销...
  • 是的,我忘了提到 +1
  • 感谢您解释发生异常时的流程@kyle
【解决方案4】:

使用 try-catch 很大程度上取决于上下文。 对我来说,没有规则告诉开发人员何时使用或不使用 try catch 块。

开发人员代码必须防止由于空参数或文件存在或数据一致性等上下文而出现明显的错误或异常。 在开发许多其他程序使用的库的情况下,该库仅捕获一些关键异常,以允许顶级程序获得有关错误和异常的更多详细信息。

例如,我们在库中有一个使用 System.IO.File.WriteAllLines 的方法。

void bool DoSomethingWithFile()
{
  try
  {
     // Some code here
     System.IO.File.WriteAllLines()
     //some code here
     return true;
  }
  catch()
  {
     LogExeption();
     return false;
  }
}

除非您在 catch 块中添加 throw,否则如何告诉顶级程序 PathTooLongException 或存在安全异常。

【讨论】:

    【解决方案5】:

    你认为可能发生错误的每一段代码都应该包含在 try catch 块中。如果您正在处理一些实时问题和应用程序,您应该在任何地方使用它。这是一个很好的编程习惯。如果您不知道会发生什么异常,只需使用 catch 块处理一般异常即可:

    try
    {
       //your code
    }
    catch (Exception ex)
    {
       //exception handling
    }
    

    或者你可以使用:

    try
    {
       //your code
    }
    catch
    {
       //your custom message
    }
    

    【讨论】:

    • 在第二种情况下,你有一个错误,甚至没有注意到它
    • 我强烈反对这种方法。 try/catch 通常应该谨慎使用——你应该只在以下情况下捕获异常:a)你可以真正处理它(例如重试)或 b)它处于应用程序的“顶级”(例如,顶级请求处理程序服务器),你基本上只是停止整个应用程序停止。在其他任何地方,都允许异常冒泡。
    • 这两个用于一般的异常处理,如果你有多个catch块,它应该是最后一个catch块。需要注意的一件事是您不能同时使用这两种方法,只能使用一种,因为它会引发语法错误。最后一个你看不到发生的错误,它只知道它发生了,它会显示你自己的自定义消息...
    • 您为什么不想至少记录异常?我不记得我上次使用这样的“空白”catch 块是什么时候了。
    • 如果你有多个 catch 块,比如说 ArgumenNullException、IndexOutOfBoundsException 等的 catch 块,并且发生了一个你没有在你的 catch 块中处理的错误......你的应用程序将会崩溃。 . general catch 块应该是最后一个 catch 块,它会确保你没有处理的错误不会导致你的应用程序崩溃......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-22
    • 1970-01-01
    • 2021-11-28
    • 2016-05-26
    • 2012-11-15
    • 1970-01-01
    相关资源
    最近更新 更多