В .NET, что если что-то не получится в блоке catch, будет всегда вызываться? - PullRequest
16 голосов
/ 24 февраля 2009

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

try
{

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

}

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

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

Ответы [ 7 ]

25 голосов
/ 24 февраля 2009

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

Если блока 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.

6 голосов
/ 24 февраля 2009

Да, наконец, всегда будет работать

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

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

6 голосов
/ 24 февраля 2009

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

4 голосов
/ 24 февраля 2009

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

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

try
{

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

}
1 голос
/ 24 февраля 2009

Блок 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 . . .

0 голосов
/ 29 января 2013

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

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

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

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

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