Почему внешний «наконец-то» не выполняется, когда внутренний «бросок» бросает? - PullRequest
6 голосов
/ 23 марта 2012

Я написал простую программу для проверки теории, что блок "finally" всегда будет выполняться независимо от того, что. Но то, что я вижу из нижеприведенного документа, заключается в том, что управление, кажется, никогда не входит во внешний финальный блок.

Я пытался использовать F5, а также Ctrl-F5 в Visual studio, и это тот же результат.

Может кто-нибудь объяснить, почему я вижу это поведение?

Вывод в окне консоли:

внутренняя защелка

внутреннее окончание

внешний фиксатор

необработанное исключение:

.. а затем приложение вылетает

public class Program
{
    static void Main()
    {
        try
        {
            try
            {
                string s = null;
                s.ToString();
            }
            catch
            {
                Console.WriteLine("inner catch");
                throw;
            }
            finally
            {
                Console.WriteLine("inner finally");
            }

            return;
        }
        catch
        {
            Console.WriteLine("outer catch");
            throw;
        }
        finally
        {
            Console.WriteLine("outer finally");
        }
    }
}

Ответы [ 2 ]

8 голосов
/ 23 марта 2012

«external finally» запускается сразу после обработки исключения.

Вот результат выполнения этого кода вне отладчика:

inner catch
inner finally
outer catch

Unhandled Exception: System.NullReferenceException: Object reference not set to
an instance of an object.
   at SOConsole.Program.Main() in c:\Users\DaveShaw\Documents\Visual Studio 11\Pro
jects\SO\SOConsole\Program.cs:line 35
outer finally
Press any key to continue . . .

Когда произошло исключениебыло отображено следующее: Exception

После того, как я нажал «Отмена», приложение возобновило работу и отобразило «внешний окончательный вариант».

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

4 голосов
/ 23 марта 2012

Приложение, вероятно, завершает работу до , когда буфер stdout очищается.

Либо добавьте точку останова к external-finally (на WriteLine), либо бросьте отличается исключение из внешнего-наконец для подтверждения.finally не пропущено: это будет серьезной ошибкой!

...