主要方法代码完全在try / catch中:这是不好的做法?

时间:2011-01-28 11:20:03

标签: c# oop programming-languages exception-handling try-catch

通常我将所有Main方法代码放在try / catch块中,如下所示:

public static void Main(string[] args)
{
   try
   {
      // code
   }
   catch (Exception e)
   {
      // code
   }
}

我这样做是为了防止任何异常从其余的程序逻辑中滑出,从而允许我对它做一些事情,比如将它显示到控制台,将其记录到文件等等。但是,我有人告诉我这是不好的做法。

你认为这是不好的做法吗?

5 个答案:

答案 0 :(得分:39)

在没有充分理由的情况下在try / catch块中包装任何代码是不好的做法。

在.NET编程模型中,应该为真正例外情况或条件保留例外。您应该尝试捕获您实际上可以做某事的异常。此外,您应该永远捕获基类System.Exception类(但更喜欢捕获可以处理的更具体的派生异常类)。如果在程序执行过程中遇到真正意外的异常,那么实际上应该崩溃。

显然,必须根据具体情况做出“正确”的答案,具体取决于// code区块中catch占位符内部的内容。但是,如果您要求一般规则或“最佳实践”,则应始终有一个特定的理由来捕获异常,而不是仅将所有代码包装在巨大的try / catch块中理所当然没有考虑它。

请注意,如果您只是想捕获为了记录或错误报告而可能发生的任何未处理的异常,那么您应该使用AppDomain.UnhandledException event。这是一个仅通知事件,因此它不允许您处理这些异常,但它是在您的应用程序崩溃后实现日志记录或错误报告功能的正确位置。


编辑:当我正在阅读Raymond Chen的优秀博客"The Old New Thing"时,我注意到他最近发表了一篇关于类似主题的文章。它特定于COM,而不是.NET Framework,但有关错误处理的一般概念同样适用于这两种环境。我想我会从这篇文章中分享一些宝石,以支持我[显然颇具争议的]意见。

  

从历史上看,COM放置了一个巨大的尝试/除了你的服务器的方法。如果您的服务器遇到通常是未处理的异常,那么巨型try / except会捕获它并将其转换为错误RPC_E_SERVERFAULT。然后它将异常标记为已处理,以便服务器保持运行,从而“通过在服务器遇到问题时保持服务器运行来提高健壮性。”

     

请注意,这实际上是一种伤害。

     

发生未处理的异常这一事实意味着服务器处于意外状态。通过捕获异常并说“不要担心,这一切都很好”,最终导致服务器运行损坏。

     

[。 。 。 ]

     

捕获所有异常并让进程继续运行假定服务器可以从意外故障中恢复。但这很荒谬。你已经知道服务器是不可恢复的吐司:它崩溃了!

     

更好的办法是让服务器崩溃,以便在发生故障时捕获崩溃转储。现在你有机会弄清楚发生了什么。

您可以[并且应该]在他的博客上阅读整篇文章:How to turn off the exception handler that COM "helpfully" wraps around your server

答案 1 :(得分:6)

如果您正在使用错误做最聪明的事情,这是一个很好的做法。这就是try / catch的用途。

如果你只是把错误扔掉(或者记录下来并扔掉它) - 特别是如果你这样做而不管异常的类型 - 这被认为是不好的做法。

这可能会引发一个问题:如果最聪明的事情就是将其记录下来并丢弃它会怎么样?我想说这将是一个例外情况。但实际上,我的代码会断言。我想我会沉迷于很多不好的做法。

答案 2 :(得分:4)

我对Cody所说的90%的人表示支持。有些情况类似于插件示例,您可能希望捕获系统异常。以下是考虑使用 WCF Web服务的另一个示例。

目标:即使遇到错误,也要使用该服务并进行处理。允许错误冒泡。

public static bool DoRemoteWebServiceWork()
{
    bool result;
    RemoteWebServiceClient client = new RemoteWebServiceClient();
    try
    {
        result = client.DoWork();
        client.Close();
    }
    catch (Exception)
    {
        client.Abort(); //dispose
        throw;//This service is critical to application function. The application should break if an exception is thrown.
        //could log end point and binding exceptions to avoid ignoring changes to the remote service that require updates to our code.
    }
    return result;
}

目标:即使遇到错误,也要使用该服务并进行处理。防止错误冒泡。

public static bool DoRemoteWebServiceWork()
{
    bool result;
    RemoteWebServiceClient client = new RemoteWebServiceClient();
    try
    {
        result = client.DoWork();
        client.Close();
    }
    catch (Exception)
    {
        client.Abort(); //dispose
        //throw; //This service is auxiliary to the applications primary function. We have no influence over the service and therefore cannot fix it.
        //could log end point and binding exceptions to avoid ignoring changes to the remote service that require updates to our code.
    }
    return result;
}

答案 3 :(得分:1)

绝对,是的,使用Exception类

是一种不好的做法

您应该关心异常的类型,而不是删除catch块上的所有异常,从而阻止它们通知系统错误。

异常类是一个基类,并且是一个可以在代码中捕获的顶级异常。使用catch块中最具体的异常,特别是您在try {...} catch {...}块中编写的唯一异常,并且只有在该特定级别上可以有效地解析它(在function,其中try .. catch block声明)

答案 4 :(得分:0)

这取决于你遇到错误时所做的事情。如果你只是抓住所有错误,看起来优雅地处理它们 - 糟糕的做法。我说这是不好的做法,即使你只在那里登录 - 在本地登录。

如果你确实做了一些事情来恢复错误(例如你自己扔了它并知道如何处理它) - 我会投票确定:)