2010-04-29 32 views
10

我希望能够在调试时打破异常......就像在Visual Studio 2008的菜单调试/异常对话框中,除非我的程序在我想要调试的位之前有许多有效的异常。我可以启用/禁用以编程方式打破例外吗?

因此,不是每次都可以使用#pragma或其他方法自动启用和禁用它,因此它只能在特定的代码段中执行?

+0

我不认为你可以,但我不知道。 – 2010-04-29 14:35:13

+1

你的程序有很多有效的异常?那是什么意思? – 2010-04-29 15:12:53

+1

这意味着我正在使用使用异常来报告代码中的条件的库。它们是警告,不是致命的,并且是API的一部分,所以我无法阻止它们,并且必须适当地捕捉它们并进行编码。 – AnthonyLambert 2010-04-29 16:26:31

回答

6

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

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

here很好的解释...

这是你把对的方法来告诉调试器的属性“无关,与我GUV”。是不是我的代码!”。容易理解的调试器会相信你,并且不会中断该方法:使用该属性可以使调试器完全跳过该方法,即使是在单步执行代码时也是如此。发生的异常,然后在方法中捕获的异常将不会进入调试器。它将把它看作是对框架程序集的调用,并且如果异常处理未处理,它将在调用堆栈的上一级报告,在调用方法的代码中。

代码示例:

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

裹在#if DEBUG您尝试catch块

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

我喜欢让外面的大括号中#如果这样,它保持在同一范围内的代码,如果内部或调试之外。

如果你还是想execption HANDELING但想更详细,你可以做到这一点

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

使用这样的事情是看起来有点清洁: [条件(“调试”) 私人无效的MyMethod(){ ... } – 2010-04-29 15:01:49

+0

我的问题是不是与尝试捕捉,但闯入调试就扔了。 ... – AnthonyLambert 2010-04-29 15:51:43

1

这对你来说有点太晚了,但这是我经常试图教导人们保守地使用例外的最大原因。只有在发生灾难性事件时才使用例外情况,并且合理继续的能力消失了。

调试程序时,我经常翻转First Chance Exceptions(Debug - > Exceptions)来调试应用程序。如果发生大量异常,很难找到某些地方出现“错​​误”的地方。

此外,它会导致一些反模式,如臭名昭着的“catch throw”并混淆真实问题。欲了解更多信息,请参阅blog post

就您的问题而言,您可以打开第一次机会仅针对特定类型的异常进行调试。除非其他例外是​​相同的类型,否则这应该工作得很好。

+0

我建议您实现按功能分组的警告异常和致命异常,您只能打开/关闭您想要陷入的异常。我认为认为异常不应该被正确使用! 我的问题是我没有写出所有生成异常的代码,并且他们在任何地方都使用一般异常,所以很难区分。 – AnthonyLambert 2010-04-29 16:43:47

0

您也可以使用断言而不是断点。举例来说,如果你只想要断点在你第二次调用该函数循环的第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)); 
     ... 
    } 
} 

所以在第一次调用工作,同时breakLoop是假的,循环将在没有断言的情况下运行,第二次通过循环会中断。

+1

您也可以在常规断点上使用命中计数功能来完成此操作。 – Jeremy 2010-04-29 16:01:53

+0

确实如此,我只是展示了一半,但我试图展示使用配置变量的一般原则以及条件来确定何时触发断言。 – 2010-04-30 11:02:15

相关问题