Можно ли программно включить / отключить взлом исключений? - PullRequest
10 голосов
/ 29 апреля 2010

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

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

Ответы [ 5 ]

6 голосов
/ 08 июня 2012

Единственный способ сделать что-то похожее на это - добавить DebuggerNonUserCodeAttribute в ваш метод.

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

Хорошее объяснение этого здесь ...

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

Пример кода:

public class Foo
{
    [DebuggerNonUserCode]
    public void MethodThatThrowsException()
    {
        ...
    {
}
2 голосов
/ 29 апреля 2010

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

1 голос
/ 29 апреля 2010

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

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

Кроме того, это приводит к некоторым антишаблонам, таким как печально известный «бросок броска», и скрывает реальные проблемы. Для получения дополнительной информации см. сообщение в блоге , которое я сделал по этому вопросу.

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

1 голос
/ 29 апреля 2010

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

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

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

Если вы по-прежнему хотите использовать 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
0 голосов
/ 29 апреля 2010

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

...