【问题标题】:Can I enable/disable breaking on Exceptions programmatically?我可以以编程方式启用/禁用异常中断吗?
【发布时间】:2011-02-13 20:26:34
【问题描述】:

我希望能够在调试时中断异常...就像在 Visual Studio 2008 的菜单调试/异常对话框中一样,除了我的程序在我想要调试的位之前有许多有效的异常。

因此,不是每次都使用对话框手动启用和禁用它,而是可以使用#pragma 或其他方法自动执行它,这样它只发生在特定的代码段中?

【问题讨论】:

  • 我不认为你可以,但我不确定。
  • 你的程序有很多有效的例外吗?这是什么意思?
  • 这意味着我正在使用使用异常来报告代码中的条件的库。它们是警告而不是致命的,并且是 API 的一部分,所以我无法阻止它们,必须捕获它们并适当地编码。

标签: c# .net visual-studio exception pragma


【解决方案1】:

接近此的唯一方法是将 DebuggerNonUserCodeAttribute 放在您的方法上。

这将确保标记方法中的任何异常都不会导致异常中断。

很好的解释here...

这是一个属性,用于告诉调试器“与我无关'。这不是我的代码!”。容易上当的调试器会相信你,并且不会中断该方法:使用该属性会使调试器完全跳过该方法,即使您正在单步执行代码;发生的异常,然后在方法中被捕获,不会闯入调试器。它会将其视为对框架程序集的调用,并且如果异常未处理,则会在调用堆栈的上一级报告,在调用该方法的代码中。

代码示例:

public class Foo
{
    [DebuggerNonUserCode]
    public void MethodThatThrowsException()
    {
        ...
    {
}

【讨论】:

    【解决方案2】:

    conditional breakpoints 呢?如果我理解正确,只有当某个变量或表达式的值为 true 时,才能触发断点。

    【讨论】:

      【解决方案3】:

      在#if DEBUG 中包装你的try catch 块

          public void Foo()
          {
              #if DEBUG
              try
              #endif
              {
                  //Code goes here
              }
              #if DEBUG
              catch (Exception e)
              {
                  //Execption code here
              }
              #endif
          }
      

      我喜欢将花括号保留在#if 之外,这样可以在调试内部或外部将代码保持在相同的范围内。

      如果您仍然想要执行处理但想要更多细节,您可以这样做

              try
              {
                  //code
              }
              catch (FileNotFoundException e)
              {
                  //Normal Code here
                  #if DEBUG
                  //More Detail here
                  #endif
              }
              #if DEBUG
              catch (Exception e)
              {
                  //handel other exceptions here
              }
              #endif
      

      【讨论】:

      • 使用这样的东西看起来更干净一些:[Conditional("Debug")] private void MyMethod() { ... }
      【解决方案4】:

      这对你来说有点晚了,但这是我经常尝试教人们保守地使用异常的最大原因。仅在发生灾难性事件并且您无法合理继续时才使用异常。

      在调试程序时,我经常打开 First Chance Exceptions (Debug -> Exceptions) 来调试应用程序。如果发生大量异常,则很难找到“错误”的地方。

      此外,它会导致一些反模式,例如臭名昭​​著的“catch throw”,并混淆了真正的问题。有关这方面的更多信息,请参阅我就该主题制作的blog post

      就您的问题而言,您可以仅针对特定类型的异常启用首次机会调试。除非其他异常属于同一类型,否则这应该可以正常工作。

      【讨论】:

      • 我建议您实现按功能分组的警告异常和致命异常,您可以仅打开/关闭要捕获的异常。我认为不应该只正确使用异常!我的问题是我没有编写所有生成异常的代码,而且它们到处都使用一般异常,所以很难区分。
      【解决方案5】:

      您也可以使用断言代替断点。例如,如果您只想在第二次调用该函数时在循环的第 5 次迭代中设置断点,您可以这样做:

      bool breakLoop = false;
      
      ...
          Work(); // Will not break on 5th iteration.
          breakLoop = true;
          Work(); // Will break on 5th iteration.
      ...
      
      public void Work() {
          for(int i=0 ; i < 10 ; i++) {
              Debug.Assert (!(breakLoop && i == 5));
              ...
          }
      }
      

      所以在第一次调用 Work 时,当 breakLoop 为 false 时,循环将在没有断言的情况下运行,第二次循环将中断。

      【讨论】:

      • 您也可以在常规断点上使用命中计数功能来完成此操作而无需代码。
      • 没错,我演示的内容有一半,但我试图演示使用配置变量以及条件来确定何时触发断言的一般原则。
      猜你喜欢
      • 1970-01-01
      • 2014-07-04
      • 1970-01-01
      • 2010-10-07
      • 1970-01-01
      • 2011-09-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多