最終的にブロック実行しますか?出口を通過した場合。?
procedure someProc;
begin
Try
Exit;
finally
do_something;
end;
end;
最終的にブロック実行しますか?出口を通過した場合。?
procedure someProc;
begin
Try
Exit;
finally
do_something;
end;
end;
はい、どこかfinally
で呼び出したとしても、ブロックは常に実行されます。それらが常に実行されExit
なければ、それらはあまり価値がないでしょう。
実行中のスレッドが非終了ループに入ったり、無期限にブロックしたり、try句の実行中に異常終了したりしない限り、finally句は常に実行されます。
関連するドキュメントには次のように記載されています(私の強調):
try...finallyステートメントの構文は次のとおりです。
try statementList1 finally statementList2 end
ここで、各statementListは、セミコロンで区切られた一連のステートメントです。
try ... finallyステートメントは、statementList1(try句)のステートメントを実行します。statementList1が例外を発生させずに終了すると、statementList2(finally節)が実行されます。statementList1の実行中に例外が発生した場合、制御はstatementList2に移されます。statementList2の実行が終了すると、例外が再発生します。Exit、Break、またはContinueプロシージャを呼び出すと、制御がstatementList1を離れる場合、statementList2が自動的に実行されます。 したがって、try句がどのように終了するかに関係なく、finally句は常に実行されます。
クイックテストアプリは、この質問に非常に迅速に答えることができたはずです。
program TestFinally;
{$APPTYPE CONSOLE}
uses
SysUtils;
begin
try
WriteLn('Before exiting');
Exit;
finally
WriteLine('In finally. If you see this, it was written after "Exit" was called');
ReadLn;
end;
end.
完全を期すために、try..finallyブロックを実行しているプロセスまたはスレッドがTerminateProcess / TerminateThreadで終了した場合、finallyブロックは実行されません。
たとえば、finallyブロックは以下のコードでは実行されません。
o := TObject.Create;
try
TerminateThread(GetCurrentThread, 0);
finally
o.Free;
end;