Могу ли я включить / отключить прерывание исключений программно?

Я хочу иметь возможность разбивать исключения при отладке... как и в диалоговом окне отладки / исключения меню Visual Studio 2008, за исключением того, что моя программа имеет много допустимых исключений, прежде чем я доберусь до бита, который я хочу отладить.

Итак, вместо того, чтобы вручную включать и отключать его, используя диалог каждый раз, можно ли сделать это автоматически с помощью #pragma или другого метода, чтобы это происходило только в определенном фрагменте кода?

5 ответов


единственный способ сделать что-то близкое к этому-поместить DebuggerNonUserCodeAttribute в свой метод.

это гарантирует, что любые исключения в отмеченном методе не вызовут перерыва в исключении.

хорошее объяснение здесь...

это атрибут, который вы ставите против метода, чтобы сказать отладчику "ничего общего со мной, шеф". Не мой код!". Доверчивый отладчик поверит вам и не сломается в этом метод: использование атрибута заставляет отладчик пропускать метод Вообще, даже когда вы проходите через код; исключения, которые происходят, а затем пойманы в методе, не будут прорываться в отладчик. Он будет относиться к нему, как если бы это был вызов сборки фреймворка, и если исключение не будет обработано, оно будет сообщено на один уровень выше стека вызовов в коде, который вызвал метод.

пример кода:

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

насчет условные точки останова? Если я правильно понимаю, вы можете иметь точку останова только тогда, когда значение определенной переменной или выражения истинно.


оберните блоки try catch в #if DEBUG

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

мне нравится держать фигурные скобки вне#, если таким образом он сохраняет код в той же области, если внутри или вне отладки.

Если вы все еще хотите handeling execption, но хотите больше деталей, вы можете сделать это

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

Это немного слишком поздно для вас, но это самая большая причина, по которой я часто пытаюсь научить людей использовать исключения консервативно. Используйте исключения только тогда, когда произошло что-то катастрофическое, и ваша способность разумно продолжать исчезла.

при отладке программы я часто переворачиваю исключения первого шанса (Debug -> Exceptions) для отладки приложения. Если происходит много исключений, очень трудно найти, куда что-то ушло "неправильный."

кроме того, это приводит к некоторым анти-паттернам, таким как печально известный "бросок улова" и запутывает реальные проблемы. Для получения дополнительной информации см. a блоге Я сделал на эту тему.

Что касается вашей проблемы, вы можете включить отладку первого шанса только для определенного типа исключения. Это должно хорошо работать, если другие исключения не относятся к тому же типу.


вы также можете использовать утверждения вместо точек останова. Например, если вы хотите только точку останова на 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 является false, цикл будет выполняться без утверждения, второй раз через цикл сломается.