Возобновление выполнения кода после исключения бросается и ломается

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

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

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)
            {
            }
        }
    }
}

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

EDIT: То, что я конкретно имею в виду, это строка Console.WriteLine(@class); похоже, не попадает, потому что, когда я запускаю его в режиме отладки, программа выходит из режима отладки. Я хочу бежать к этой линии и останавливаться на ней.

Спасибо

Ответы

Ответ 1

Ну, у вас нет кода после блоков 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 running after the exception!");
}

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

UPDATE

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

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

Ответ 2

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

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

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

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

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

Ответ 4

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

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

public static class ControlFlow
{
  public static Exception ResumeOnError(Action action)
  {
    try
    {
      action();
      return null;
    }
    catch (Exception caught)
    { 
      return caught;
    }
  }
}

И тогда его можно использовать следующим образом.

public static void Main()
{
  ControlFlow.ResumeOnError(() => { throw new NotSupportedException(); });
  ControlFlow.ResumeOnError(() => { Console.WriteLine(); });
  ControlFlow.ResumeOnError(() => { Console.ReadLine(); });
}

Ответ 5

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

Ответ 6

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

Console.ReadLine();

Ответ 7

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

Ответ 8

Вы можете использовать функцию "переключение" при отладке для достижения этой цели на основе каждого запуска.

Ответ 9

Какой-то простой код, который я собрал, чтобы поймать исключения, которые выбрасываются внутри блока catch:

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

    try { SomeMethod2(); }
    catch { }

    try { SomeMethod3(); }
    catch { }
}
finally
{
    //cleanup goes here
}

Ответ 10

public static void Main()
{
    for (int j = 0; j <= 100000; j++)
    {
        try
        {
                // TODO: Application logic...
        }
        catch
        {
                System.Threading.Thread.Sleep(1000);
        }
    }
}