C# “наконец” блок ВСЕГДА выполняются? [дубликат]

68
задан Community 23 May 2017 в 12:17
поделиться

11 ответов

6
ответ дан 24 November 2019 в 14:06
поделиться

Из MSDN try-finally (Справочник по C #)

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

4
ответ дан 24 November 2019 в 14:06
поделиться

Блок finally будет запущен прямо между этими строками:

message = "You will not win!";
return;
2
ответ дан 24 November 2019 в 14:06
поделиться

Да, при нормальных обстоятельствах (как указывали многие другие).

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

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

http://msdn.microsoft.com/en-us/library/zwc8s4fz.aspx

2
ответ дан 24 November 2019 в 14:06
поделиться

Нет, не будет. Он всегда будет выполняться, если приложение все еще запущено (за исключением исключения FastFail, MSDN link, как отметили другие). Он выполнится, когда выйдет из части блока try/catch.

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

81
ответ дан 24 November 2019 в 14:06
поделиться

Из MSDN C# спецификация оператора try:

Утверждения блока finally всегда выполняются, когда управление покидает оператор try. Это верно независимо от того, происходит ли передача управления в результате обычного выполнения, в результате выполнения break, continue, goto или return оператора, или в результате распространения исключения из оператора try.

Источник

Есть случаи, когда блок finally не будет выполнен:

  1. Environment.FailFast
  2. Не улавливаемые типы исключений
  3. Power Failure
50
ответ дан 24 November 2019 в 14:06
поделиться

Правильный ответ - да.

Попробуйте отладить свою программу и установить точку останова и посмотреть, как элемент управления все еще попадает в блок finally.

1
ответ дан 24 November 2019 в 14:06
поделиться

Простой ответ Да. Но есть некоторые "исключения" из правила.

0
ответ дан 24 November 2019 в 14:06
поделиться

Да, finally всегда выполняется, а вот вызовет ли код в блоке finally исключение - это уже другая история.

1
ответ дан 24 November 2019 в 14:06
поделиться

Не совсем верно, что finally всегда будет выполняться. См. этот ответ от Haacked :

Две возможности:

  • StackOverflowException
  • ExecutingEngineException

Блок finally не будет выполнен когда есть StackOverflowException поскольку в стеке нет места для даже выполнить еще какой-то код. Так и будет также не называться, когда есть ExecutingEngineException, то есть очень редко.

Фактически, для любого вида асинхронного исключения (например, StackOverflowException , OutOfMemoryException , ThreadAbortException ) выполнение блока finally не гарантируется.

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

Фактически, есть также как минимум еще один случай, когда finally не выполняется, как описано Брайаном Расмуссеном в теперь удаленном вопросе :

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

Приведенный ниже код иллюстрирует проблему

static void Main(string[] args) {
   try {
      DisposableType d = new DisposableType();
      d.Dispose();
      d = null;
      GC.Collect();
      GC.WaitForPendingFinalizers();
   } catch {
      Console.WriteLine("catch");
   } finally {
      Console.WriteLine("finally");
   }
}

public class DisposableType : IDisposable {
   public void Dispose() {
   }

   ~DisposableType() {
      throw new NotImplementedException();
   }
}

Надежная попытка / catch / finally должна будет использовать Ограниченные области выполнения (CER) . Пример предоставлен MSDN:

[StructLayout(LayoutKind.Sequential)]
struct MyStruct
{
    public IntPtr m_outputHandle;
}

sealed class MySafeHandle : SafeHandle
{
    // Called by P/Invoke when returning SafeHandles
    public MySafeHandle()
        : base(IntPtr.Zero, true)
    {
    }

    public MySafeHandle AllocateHandle()
    {
        // Allocate SafeHandle first to avoid failure later.
        MySafeHandle sh = new MySafeHandle();

        RuntimeHelpers.PrepareConstrainedRegions();
        try { }
        finally
        {
            MyStruct myStruct = new MyStruct();
            NativeAllocateHandle(ref myStruct);
            sh.SetHandle(myStruct.m_outputHandle);
        }

        return sh;
    }
}

Отличным источником информации является следующая статья:

Рекомендации по надежности

34
ответ дан 24 November 2019 в 14:06
поделиться

Нет, это не так.

Однако есть только один способ обойти это - Environment.FailFast () . См. http://msdn.microsoft.com/de-de/library/ms131100.aspx . Во всех остальных случаях гарантируется выполнение финализаторов; -)

Метод FailFast записывает сообщение строка в приложение Windows журнал событий, создает дамп вашего приложение, а затем завершает текущий процесс. Строка сообщения также включается в отчеты об ошибках Microsoft.

Используйте метод FailFast вместо Метод выхода для прекращения вашего приложение, если состояние вашего приложение повреждено и не подлежит ремонту, и выполнение вашего приложения блоки try / finally и финализаторы будут испорченные программные ресурсы.

1
ответ дан 24 November 2019 в 14:06
поделиться
Другие вопросы по тегам:

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