Выполняются ли операторы в блоке finally в этом фрагменте кода? - PullRequest
22 голосов
/ 23 декабря 2011

Будет ли наконец исполняться блок? если я пройду выход;

procedure someProc;
begin
    Try
      Exit;
    finally
     do_something;
    end;
end;

Ответы [ 4 ]

29 голосов
/ 23 декабря 2011

Да, блоки finally всегда выполняются, даже если вы вызываете Exit где-нибудь. Они бы не стоили много, если бы они не были всегда казненными.

26 голосов
/ 23 декабря 2011

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

В соответствующей документации говорится (выделено мое):

Синтаксис оператора try ... finally:

try 
  statementList1
finally
  statementList2 
end 

где каждый StatementList является последовательностью операторов разделены точками с запятой.

Оператор try ... finally выполняется операторы в StatementList1 (предложение try). Если StatementList1 заканчивается без повышения исключений, StatementList2 (предложение finally) выполняется. Если исключение возникает во время выполнения StatementList1, управление передается в StatementList2; однажды StatementList2 завершает выполнение, исключение повторно вызывается. Если звонок на Процедура Exit, Break или Continue приводит к тому, что контроль покидает StatementList1, StatementList2 автоматически выполняется. Таким образом, предложение finally всегда выполняется независимо от того, как заканчивается предложение try.

12 голосов
/ 23 декабря 2011

Быстрое тестовое приложение могло бы очень быстро ответить на этот вопрос.

9 голосов
/ 23 декабря 2011

Для полноты - блок finally будет не выполняться, если процесс или поток, выполняющий блок try..finally, завершается с помощью TerminateProcess / TerminateThread.

Например, блок finallyне будет выполняться в приведенном ниже коде.

o := TObject.Create;
try
  TerminateThread(GetCurrentThread, 0);
finally
  o.Free;
end;
...