Возобновление выполнения кода после исключения генерируется и перехватывается - PullRequest
27 голосов
/ 09 июня 2010

Как можно возобновить выполнение кода после возникновения исключения?

Например, возьмите следующий код:

namespace ConsoleApplication1
{
    public class Test
    {
        public void s()
        {
            throw new NotSupportedException();
            string @class = "" ;
            Console.WriteLine(@class);
            Console.ReadLine();
        }
    }

    public class Program
    {
        public static void Main(string[] args)
        {
            try
            {
                new Test().s();
            }
            catch (ArgumentException x)
            {
            }
            catch (Exception ex)
            {
            }
        }
    }
}

После перехвата исключения при пошаговом выполнении программаперестанет работать.Как я могу продолжать выполнение?

РЕДАКТИРОВАТЬ: Что я конкретно имею в виду, это строка Console.WriteLine (@class);похоже, не ударил, потому что, когда я запускаю его в режиме отладки, программа выходит из режима отладки.Я хочу бежать к этой линии и остановиться на ней.

Спасибо

Ответы [ 10 ]

33 голосов
/ 09 июня 2010

Ну, у вас нет кода после блоков catch, поэтому программа остановится. Не уверен, что ты пытаешься сделать.

Следующее должно быть доказательством того, что программа не просто «останавливается» после блоков catch. Он выполнит код после блоков catch, если есть код для выполнения:

static void Main(string[] args)
{
    try
    {
        new Test().s();
    }
    catch (ArgumentException x)
    {
        Console.WriteLine("ArgumentException caught!");
    }
    catch (Exception ex) 
    { 
        Console.WriteLine("Exception caught!");
    }

    Console.WriteLine("I am some code that's running after the exception!");
}

Код напечатает соответствующую строку в зависимости от того, какое исключение было перехвачено. Затем он напечатает I am some code that's running after the exception! в конце.

UPDATE

В своем редактировании вы спросили, почему Console.WriteLine(@class); не похоже на попадание. Причина в том, что вы явно бросаете исключение в самой первой строке вашего s() метода; все, что следует, игнорируется. Когда встречается исключение, выполнение останавливается, и исключение распространяется по стеку вызовов до тех пор, пока соответствующий обработчик не сможет его обработать (это может быть блок catch, который соответствует try, который упаковывает рассматриваемый оператор в тот же метод или это может быть блок catch дальше по стеку вызовов. Если соответствующий обработчик не найден, программа завершит работу с помощью трассировки стека [по крайней мере, в Java - не уверен, что то же самое происходит в C #]).

Если вы хотите попасть в строку Console.WriteLine, вам не следует явно выдавать исключение в начале метода.

8 голосов
/ 09 июня 2010

Звучит так, будто вы хотите возобновляемых исключений.C # не делает возобновляемых исключений, и я сомневаюсь, что CLR поддерживает их.

Цель выброса исключения состоит в том, чтобы прервать функцию и всю операцию (стек вызовов), если / когда что-то в вызовесреда (параметры, состояние объекта, глобальное состояние) делает работу функции невозможной или недействительной.Передача нулевого параметра функции, которая должна делить количество на этот параметр, например.Деление на ноль не даст значимого результата, и если это единственная цель функции, то функция также не может вернуть значимый результат.Итак, брось исключение.Это заставит выполнение перейти к ближайшему перехвату или, наконец, заблокировать стек вызовов.Нет возврата к функции, которая вызвала исключение.

Если вы хотите войти в свой код в отладчике, чтобы отследить вызовы Console.WriteLine (), вам нужно удалить новую строку выброса NotSupportedException ()из вашего кода и перекомпилируйте.

7 голосов
/ 09 июня 2010

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

class Test 
{ 
    public void s() 
    { 
        try
          {
              // Code that may throw an exception
              throw new NotSupportedException();
          } 
          catch(Exception ex)
          {
              // Handle the exception - log?, reset some values?
          }
          string @class = "" ; 
          Console.WriteLine(@class); 
          Console.ReadLine(); 
    } 
} 

Вы также можете вернуть bool или другое значение, чтобы указать состояние.

3 голосов
/ 09 июня 2010

Отказ от ответственности: я не предполагаю, что вы действительно делаете это.

Вы можете имитировать старый стиль VB On Error Resume Next с помощью следующего кода.использоваться следующим образом.

public static void Main()
{
  ControlFlow.ResumeOnError(() => { throw new NotSupportedException(); });
  ControlFlow.ResumeOnError(() => { Console.WriteLine(); });
  ControlFlow.ResumeOnError(() => { Console.ReadLine(); });
}
1 голос
/ 17 июня 2013

Несколько простых кодов, которые я собрал, чтобы перехватывать исключения, которые выбрасываются внутри блока catch:

try
{
    //do code here
}
catch (Exception ex)
{
    try { SomeMethod1(); }
    catch { }

    try { SomeMethod2(); }
    catch { }

    try { SomeMethod3(); }
    catch { }
}
finally
{
    //cleanup goes here
}
0 голосов
/ 16 июля 2016
public static void Main()
{
    for (int j = 0; j <= 100000; j++)
    {
        try
        {
                // TODO: Application logic...
        }
        catch
        {
                System.Threading.Thread.Sleep(1000);
        }
    }
}
0 голосов
/ 09 июня 2010

Вы можете использовать функцию «пошагового» в отладке, чтобы достичь этого для каждого запуска.

0 голосов
/ 09 июня 2010

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

0 голосов
/ 09 июня 2010

Программа останавливается, потому что в методе Main () отсутствует следующий код! Вы можете добавить следующую строку в ваш код, чтобы программа продолжала работать до тех пор, пока не появится консольный ввод:

Console.ReadLine();
0 голосов
/ 09 июня 2010

Выполнение все еще продолжается, но после обнаружения исключения код отсутствует.Если вы хотите многократно вызывать s, подумайте об упаковке блока try / catch в цикл while.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...