仅在 Release 中尝试捕获的更好方法?
Posted
技术标签:
【中文标题】仅在 Release 中尝试捕获的更好方法?【英文标题】:Better way for try-catch only in 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 变量),并且抛出异常而不是捕获它真的很棒(当然仅在开发模式下),因为带有堆栈跟踪的错误页面将显示出来,因此我们可以更快地跟踪错误。
上面的代码有没有更简洁的写法?
【问题讨论】:
我不明白这样做(想象有一种方法)如何使您免于“缺点是它会在同一类型的每个异常时中断,无论它发生在哪里” 你需要捕获全局异常吗?并在其上设置断点,您将在调试器中获得带有堆栈跟踪的完整异常。 谷歌asp mvc global error handler @user5328504 抱歉,我改写了我的意思。 【参考方案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】:
两件事:
#if DEBUG
你要去多少个地方?
Console.WriteLine
在 ASP.NET 中毫无意义。请参阅this 了解更多信息。
您应该做的是将错误记录到数据库、文件或其他内容中。这将避免代码中的所有#if DEBUG
s。有关日志记录的更多信息,请参阅this。
这有额外的好处:
-
您将能够看到您的错误是什么样的,因此当您投入生产时,您将获得相同的信息。如果您没有足够的信息,在日志中,在开发过程中,它让您有机会更改错误消息并确保堆栈跟踪存在。这在您投入生产时会很有帮助,因为现在您有更好的错误。
您的代码更简洁
【讨论】:
我确实认为你应该在未来的某个地方遵循这个建议。你目前的方法会变得丑陋 @user5328504 对不起,你是什么意思? 我的意思是你应该(在未来)制定一个更好的日志记录机制。现在不用担心,下次告诉自己如何处理跟踪和日志记录。不过,现在不要为此失眠 我不确定你是在告诉我那个还是 OP 但好吧我还是会去睡觉 我也不会。我也不会以上是关于仅在 Release 中尝试捕获的更好方法?的主要内容,如果未能解决你的问题,请参考以下文章
UIButton - 仅在没有待处理事件时调用 Release?
c# Naudio 音频电平捕获和显示,仅在打开录音属性时有效