仅在Release中尝试catch的更好方法是什么?

时间:2017-04-26 03:13:16

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

当我想调试抛出异常的应用程序时,这意味着我需要像这样禁用try-catch块:

#if !DEBUG
                try
                {
#endif
                    // Do something
#if !DEBUG
                }
                catch (ArgumentException)
                {
                    Console.WriteLine("Something wrong");
                }
#endif

注意:我知道中断Visual Studio的处理异常,但缺点是它会在同一类型的每个异常处中断。 编辑以改写我的意思:例如,函数A和B都抛出NullReferenceException,但我只想检查A何时抛出它,而不是B(B中处理的NulRefExc已经正确)。

有人可能会问为什么我需要这个。通常我在没有调试的情况下运行ASP.NET MVC代码(但仍然在Debug build中,它有DEBUG变量),抛出异常非常好而不是捕获它(当然只在dev模式下),因为带有堆栈跟踪的错误页面将显示,因此我们可以更快地跟踪错误。

有没有更简洁的方法来编写上层代码?

3 个答案:

答案 0 :(得分:4)

从C#6开始,您也可以使用exception filters

try
{
    // Do something
}
catch (ArgumentException) when (!Env.Debugging)
{
    // Handle the exception
}

Env.Debugging定义为

public static class Env
{
#if DEBUG
    public static readonly bool Debugging = true;
#else
    public static readonly bool Debugging = false;
#endif
}

作为额外奖励,当未捕获时,您将在异常对象中获得原始调用堆栈(由于when测试失败,即在调试中)。使用重新抛出的异常,您必须提供原始异常作为内部异常,并做出一些额外的努力来处理它。

此方法还允许基于其他条件启用/禁用异常处理,例如web.config设置,这将允许您在不重新编译的情况下进行切换:

public static class Env
{
    public static readonly bool Debugging =
      Convert.ToBoolean(WebConfigurationManager.AppSettings["Debugging"]);
}

答案 1 :(得分:3)

只是一个想法 离开try catch

然后做

 catch (ArgumentException)
                {
#if DEBUG
                throw SomeCustomExceptionYouCatchWith_break_on_handled_exception();
#endif
                    Console.WriteLine("Something wrong");
                }

答案 2 :(得分:1)

两件事:

  1. 你要去#if DEBUG多少个地方?
  2. Console.WriteLine在ASP.NET中毫无意义。有关详情,请参阅this
  3. 您应该做的是将错误记录到数据库,文件或其他内容。这将避免代码中的所有#if DEBUG。有关日志记录的详情,请参阅this

    这还有其他好处:

    1. 您将能够看到您的错误是什么样的,因此当您投入生产时,您将获得相同的信息。如果在日志中没有足够的信息,那么在开发过程中,它会让您有机会更改错误消息并确保堆栈跟踪存在。这将在您投入生产时很有用,因为现在您有更好的错误。
    2. 您的代码更清晰