Подтвердить что ты не робот

В .NET, что, если что-то не удается в блоке catch, будет, наконец, всегда вызвано?

В блоке try/catch/finally, например:

try
{

}
catch()
{
   // code fails here
}
finally
{ 

}

Итак, если в блоке catch есть исключение, то, наконец, всегда будет вызван?

Что делать, если нет, будет ли код после того, как блок catch будет запущен?

4b9b3361

Ответ 1

Предполагая, что процесс не прерывается (или зависает, конечно), блок finally всегда будет выполнен.

Если нет окончательного блока, исключение из блока catch будет просто выброшено в стек. Обратите внимание, что исходное исключение, из-за которого будет выполняться блок catch, будет эффективно потеряно.

Исключения

Как отметил Джаред, переполнение стека приведет к тому, что блок finally не будет выполнен. Я считаю, что это внезапно прекращает программу, но я могу ошибаться. Здесь пример кода:

using System;

public class Test
{    
    static void Main()
    {
        // Give the stack something to munch on
        int x = 10;
        try
        {
            Main();
            Console.WriteLine(x);
        }
        finally
        {
            Console.WriteLine("Finally");
        }
    }  
}

Результаты:

Процесс завершается из-за исключения StackOverflowException.

Ответ 2

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

Ответ 3

Да, наконец, будет всегда выполняться

Нет кода после того, как блок catch не будет запущен.

Даже с окончательным блоком любой код, следующий за блоком finally, не будет запущен.

Ответ 4

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

Извлеченный урок: не делайте вещи в блоке catch, которые могут бросать, если вы можете помочь ему; если нужно, вставьте блок try/catch.

try
{

}
catch()
{
  try
  {
    // code fails here
  }
  catch
  {
    // handle that. Or not. 
  }
}
finally
{ 

}

Ответ 5

Блок finally всегда будет выполнен. Из MSDN:

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

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

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

class Program {
    static void Main(string[] args) {
        try {
            Console.WriteLine("Trying!");
            throw new Exception();
        }
        catch (Exception e) {
            Console.WriteLine("Catching {0}!", e.Message);
            throw new Exception();
        }
        finally {
            Console.WriteLine("Finally!");
        }
    }
}

Выводится:

Trying!
Catching Exception of type 'System.Exception' was thrown.!

Unhandled Exception: System.Exception: Exception of type 'System.Exception' was
thrown.
at TestFinally.Program.Main(String[] args) in C:\Documents and Settings\Me\My
Documents\Visual Studio 2008\Projects\TestFinally\TestFinally\Program.cs:line 15
Finally!
Press any key to continue . . .

Ответ 6

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

Код после точки исключения в блоке catch не будет вызван.

Ответ 7

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

  • В случае выполнения StackOverflowException, запущенного во время выполнения
  • System.Environment.FastFail
  • Environment.Exit
  • Если "фоновый" поток завершается, потому что основная программа который он принадлежит, заканчивается.
  • Неожиданное завершение работы:)