C#Try-Catch&异常处理

时间:2012-04-24 02:28:01

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

在当前项目的代码的各个部分中,不断使用

try
{
    //code
}
catch(Exception e)
{
    //display nicely formatted error message
}

我的问题是,假设代码处理所有已知/假定的错误(例如检查对象是否为空等),是否应该在代码中放置try-catch,以显示应用程序全局格式的错误?

或者更好的做法是让错误引发异常并让应用程序自然崩溃?

由于

4 个答案:

答案 0 :(得分:6)

捕获这样的所有异常是一种很好的做法,除了在应用程序的顶层,您显示一个很好的错误消息。如果做得好,它可以保留最终用户对您的程序的感知,因为略微错误,但整体上是合理的。相比之下,让您的应用程序崩溃是让最终用户相信您的应用程序无法修复的最简单方法。

就异常预防而言,有两种主要的异常 - 编程错误(空指针,类强制转换,超出范围等)和环境错误(找不到文件,网络路径不可用,用户输入错误等等。你可以而且应该避免使用第一种,并准备好处理第二种。

答案 1 :(得分:3)

class PerformTask
{
    public void ConnectToDB(requiredParams)
    {


    }
}

class PerformTaskConsumer
{
   public void SomeMethod()
   {
      try
      {
         PerformTask obj = new PerformTask();
      }

      catch(RelaventExceptions)
      {

      }
   } 


}

如果可以,请尽量避免异常。如果发生异常,请将其留给调用者他想要对异常做什么。调用者可能决定显示关于异常的格式正确的消息,或者决定崩溃或者什么都没有。

Eric Lippert有一篇关于例外的好文章。 here

答案 2 :(得分:2)

这里有两种不同的思想流派,两者的支持者经常感到震惊和惊讶,任何人都可能相信另一种方式。最后,这是一个偏好问题,以及您的目标用户群期望和/或愿意接受的内容,更重要的是,您了解应用程序的功能。 (你的问题暗示你没有编写所有涉及的代码,所以最后一点可能比你想象的要复杂。)

首先,我假设您在这里讨论的是最终用户应用程序,而不是类库。几乎没有理由在类库中捕获未明确处理的异常。你总是把这个决定留给来电者。

然而,在最终用户应用程序中,最终决定权归你所有,因为调用链上没有任何人。在这种情况下,您有两个广泛的选择:

快速失败

有些人认为,遇到错误时,最好尽快让应用程序崩溃。虽然它看起来有点反效果,但要记住遇到未处理的异常意味着什么:你真的不知道出了什么问题;甚至像错误记录代码这样简单的事情也可能以您不期望的方式运行。

如果您正在呼叫站点正确处理异常,那么当出现真正非常糟糕的事情时,您应该只收到这种“意外”错误:内存不足,堆栈损坏等等。你不能做的事情无论如何,真的可以恢复,所以没有必要尝试。

正常失败

其他人认为您应尽可能尝试隔离错误,以防止用户丢失信息。如果您的应用程序足够模块化,那么一个区域的完全失败可能对另一个区域的数据完全没有影响。

这是一个风险更高的主张:你必须非常小心,不要让自己陷入不稳定的状态。它要求您确实知道,失败代码中的任何内容都不会从代码的其他部分更改状态。

结论

像往常一样,“正确”的答案可能在中间的某个地方。通常,以不一致状态运行的风险几乎总是允许应用程序死亡的好理由。当然,你可能仍然希望在这里做一些级别的日志记录,你可以通过几种方式完成。我的偏好不是为此使用例外,而是挂钩顶层的各种“未处理的例外”事件,如thisthisthis。在这些事件处理程序中记录您的异常,可能会显示“友好”错误对话框,然后关闭您的应用程序。例如,我们在我们生成的WPF应用程序中添加了类似的内容:

<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             DispatcherUnhandledException="UnhandledException">


private void UnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
    logger.FatalException("OH NOES! Bad stuff happened, bailing out.", e.Exception);
    MessageBox.Show("holy cow something bad happened:\r\n" + e.Exception.Message);
}

但是,有些地方可以捕捉所有例外情况;这主要限于所有数据将被丢弃的地方,无论如何。例如,打印或导出已完成操作的结果可能会“安全”失败,对应用程序的其余部分没有任何不良影响。您可能不希望您的应用程序因为用户没有打印机而崩溃。 (我甚至遇到过一个第三方打印库的情况,它在错误中明确地抛出了System.Exception ...)但你必须非常小心,你知道你在做什么,而你的数据是真正与系统的其他部分隔离开来。

答案 3 :(得分:0)

提示您知道将try ... catch块放在哪里。

放置一个全局异常处理程序,以捕获未处理的所有异常。记录堆栈跟踪和异常,向最终用户显示道歉并关闭程序(永远不要尝试继续)。

让应用程序运行,当它崩溃时,检查原因并正确处理异常,并尽可能使用最具体的异常。

请记住: 异常是针对异常的,而不是针对正常的程序行为。