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

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

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

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

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

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

Спасибо

29
задан ManoDestra 18 July 2016 в 17:44
поделиться

8 ответов

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

Код напечатает соответствующую строку в зависимости от перехваченного исключения. Затем он напечатает Я - некоторый код, который выполняется после исключения! в конце.

ОБНОВЛЕНИЕ

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

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

35
ответ дан 28 November 2019 в 01:33
поделиться

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

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

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

10
ответ дан 28 November 2019 в 01:33
поделиться

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

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(); 
    } 
} 

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

8
ответ дан 28 November 2019 в 01:33
поделиться

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

0
ответ дан 28 November 2019 в 01:33
поделиться

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

Console.ReadLine();
0
ответ дан 28 November 2019 в 01:33
поделиться

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

0
ответ дан 28 November 2019 в 01:33
поделиться

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

Вы можете имитировать старый стиль 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(); });
}
3
ответ дан 28 November 2019 в 01:33
поделиться

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

0
ответ дан 28 November 2019 в 01:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: