C# 只有在发布时才尝试捕获的更好方法?

C# 只有在发布时才尝试捕获的更好方法?,c#,asp.net,exception,try-catch,C#,Asp.net,Exception,Try Catch,当我想调试引发异常的应用程序时,这意味着我需要禁用try-catch块,如下所示: #if !DEBUG try { #endif // Do something #if !DEBUG } catch (ArgumentException) { Console

当我想调试引发异常的应用程序时,这意味着我需要禁用try-catch块,如下所示:

#if !DEBUG
                try
                {
#endif
                    // Do something
#if !DEBUG
                }
                catch (ArgumentException)
                {
                    Console.WriteLine("Something wrong");
                }
#endif
注意:我知道VisualStudio的中断处理异常,但缺点是它会在同一类型的每个异常上中断编辑以重新表述我的意思:例如,函数A和B都抛出NullReferenceException,但我只想检查A何时抛出它,而不是B(B中已处理的NulRefExc已经正确)

有人可能会问我为什么需要它。通常我在不进行调试的情况下运行ASP.NET MVC代码(但仍在调试版本中,其中包含调试变量),抛出异常而不是捕获异常非常好(当然,仅在开发模式下),因为将显示带有堆栈跟踪的错误页,因此我们可以更快地跟踪错误

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

只是一个想法 留下来试试看

那就做吧

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

  • 如果调试,您将把
    #放入多少个位置
    
  • Console.WriteLine
    在ASP.NET中毫无意义。更多信息,请参阅
  • 您应该做的是将错误记录到数据库、文件或其他地方。这将避免所有的
    #if DEBUG
    s覆盖整个代码。有关日志记录的更多信息,请参阅

    这还有其他好处:

  • 您将能够看到错误的样子,因此当您投入生产时,您将获得相同的信息。如果在开发过程中日志中没有足够的信息,则可以更改错误消息并确保堆栈跟踪在那里。这将有助于您投入生产,因为现在您有更好的错误
  • 你的代码更干净
  • 由于C#6,您也可以使用:

    try
    {
        // Do something
    }
    catch (ArgumentException) when (!Env.Debugging)
    {
        // Handle the exception
    }
    
    在某处定义为环境调试的

    public static class Env
    {
    #if DEBUG
        public static readonly bool Debugging = true;
    #else
        public static readonly bool Debugging = false;
    #endif
    }
    
    作为额外的奖励,当异常对象未被捕获时,您将在异常对象中获得原始调用堆栈(由于
    测试失败时,即在调试中)。对于重新抛出的异常,您必须提供原始异常作为内部异常,并进行一些额外的处理

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

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

    我看不出这样做(想象有一种方法)将如何使您免于“缺点是它会在同一类型的每个异常处中断,无论它发生在哪里”您需要捕获全局异常吗?并在其上设置断点,您将在调试器中获得带有堆栈跟踪的完整异常。Google@user5328504抱歉,我重新表述了我的意思。您甚至可以让自定义异常将原始异常作为构造函数参数获取哇,这太好了!正是我需要的!如果只是一个简单的调试代码,
    抛出之间的code>语句#如果
    指令足够:)@DatVM在生产中不写入
    控制台
    ,而是写入日志@是的,对不起,上面的代码只是我的示例,我知道Console.WriteLine(几乎)什么都不做。我的问题的主要目的是在开发环境中,堆栈跟踪是我们最关心的问题(但是,我们仍然有用于生产的try-catch)很酷!我从没想过这个。现在这个问题有两个很好的答案,我不知道该标记哪个。另外:
    public const bool
    是一个较短的版本。对于.NET核心,您将使用:
    catch(Exception ex)when(!\u hostingEnvironment.IsDevelopment())
    并在构造函数中注入
    IHostingEnvironment
    。我确实认为您应该在将来的某个地方遵循这个建议。您当前的方法将会增长ugly@user5328504对不起,你是什么意思?我的意思是你应该(将来)制定一个更好的日志记录机制。现在不要担心,下次再告诉自己如何处理跟踪和日志记录。我不知道你是在告诉我这件事还是在说手术,但好吧,我会去睡觉的。我也是。我也会去睡觉的