【问题标题】:Better way for try-catch only in Release?仅在 Release 中尝试捕获的更好方法?
【发布时间】:2017-04-26 03:13:15
【问题描述】:

当我想调试抛出异常的应用程序时,这意味着我需要像这样禁用 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 已经正确)。 p>

有人可能会问我为什么需要它。通常我在没有调试的情况下运行 ASP.NET MVC 代码(但仍在调试构建中,它具有 DEBUG 变量),并且抛出异常而不是捕获它真的很棒(当然仅在开发模式下),因为带有堆栈跟踪的错误页面将显示出来,因此我们可以更快地跟踪错误。

上面的代码有没有更简洁的写法?

【问题讨论】:

  • 我不明白这样做(想象有一种方法)如何使您免于“缺点是它会在同一类型的每个异常时中断,无论它发生在哪里”
  • 你需要捕获全局异常吗?并在其上设置断点,您将在调试器中获得带有堆栈跟踪的完整异常。
  • @user5328504 抱歉,我改写了我的意思。

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


【解决方案1】:

从 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"]);
}

【讨论】:

  • 酷!我从来没有想过这个。现在这个问题有 2 个很好的答案,我不知道要标记哪个。 P.s:public const bool 是一个较短的版本。
  • 对于 .NET Core,您可以使用:catch (Exception ex) when (!_hostingEnvironment.IsDevelopment()) 并在构造函数中注入 IHostingEnvironment
【解决方案2】:

只是一个想法 离开try catch

然后做

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

【讨论】:

  • 你甚至可以让自定义异常获取原始异常作为构造函数参数
  • 哇,这太棒了!正是我需要的!如果只是一个简单的调试代码,#if 指令之间的throw; 语句就足够了:)
  • @DatVM 在生产中不会写入Console,而是将其写入日志。 Where does console writeline go in asp
  • @CodingYoshi 是的,抱歉上面的代码只是我的例子,我知道 Console.WriteLine (几乎)什么都不做。我的问题主要目标是在开发环境中,堆栈跟踪是我们最关心的问题(但我们仍然有用于生产的 try-catch)
【解决方案3】:

两件事:

  1. #if DEBUG 你要去多少个地方?
  2. Console.WriteLine 在 ASP.NET 中毫无意义。请参阅this 了解更多信息。

您应该做的是将错误记录到数据库、文件或其他内容中。这将避免代码中的所有#if DEBUGs。有关日志记录的更多信息,请参阅this

这有额外的好处:

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

【讨论】:

  • 我确实认为你应该在未来的某个地方遵循这个建议。你目前的方法会变得丑陋
  • @user5328504 对不起,你是什么意思?
  • 我的意思是你应该(在未来)制定一个更好的日志记录机制。现在不用担心,下次告诉自己如何处理跟踪和日志记录。不过,现在不要为此失眠
  • 我不确定你是在告诉我那个还是 OP 但好吧我还是会去睡觉
  • 我也不会。我也不会
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-25
相关资源
最近更新 更多