我可以通过编程方式启用/禁用异常中断吗?

时间:2010-04-29 14:29:08

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

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

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

5 个答案:

答案 0 :(得分:6)

接近这一点的唯一方法是在您的方法上放置DebuggerNonUserCodeAttribute。

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

对它的好解释here ......

  

这是一个针对方法的属性,告诉调试器“与我没关系guv'。不是我的代码!”。容易上当的调试器会相信你,并且不会破坏该方法:使用该属性会使调试器完全跳过该方法,即使是在单步调试代码时也是如此;发生的异常,然后在方法中捕获将不会进入调试器。它将它视为对Framework程序集的调用,并且如果异常未处理,则会在调用该方法的代码中向调用堆栈报告一级。

代码示例:

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

答案 1 :(得分:2)

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

答案 2 :(得分:1)

在#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

答案 3 :(得分:1)

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

在调试程序时,我经常翻转First Chance Exceptions(Debug - > Exceptions)来调试应用程序。如果发生了很多例外情况,很难找到出现“错误”的地方。

此外,它导致一些反模式,如臭名昭着的“抓住投掷”,并混淆真正的问题。有关详细信息,请参阅我对该主题所做的blog post

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

答案 4 :(得分: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));
        ...
    }
}

因此,在第一次调用Work时,虽然breakLoop为false,但循环将在没有断言的情况下运行,第二次循环将会中断。