2011-12-23 9 views
17

¿Finalmente se bloqueará la ejecución? si paso la salida; ?¿Las instrucciones en el bloque Finally aún se ejecutan en este fragmento de código?

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

Nota al margen: 'while True do tratar salida; finalmente Continuar; end; 'no se compilará; consulte [Diversión con infinitos bucles en Delphi y Java] (http://mikejustin.wordpress.com/2008/07/13/fun-with-infinite-loops-in-delphi-and- java /) – mjn

Respuesta

24

Sí, finally bloques siempre se ejecutan, incluso si se llama a Exit en alguna parte. No valdrían mucho si no se ejecutaran siempre.

10

Una aplicación de prueba rápida podría haber respondido a esta pregunta muy rápido.

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. 
21

El finalmente siempre se ejecutará cláusula, a menos que el subproceso en ejecución entra en un bucle no termina, bloques indefinidamente o se termina de manera anormal, mientras que la ejecución de la cláusula try.

Los estados pertinentes documentation (el énfasis es mío):

La sintaxis de una sentencia try ... finalmente es

try 
    statementList1 
finally 
    statementList2 
end 

donde cada statementList es una secuencia de instrucciones delimitados por punto y coma.

La declaración try ... finally ejecuta las instrucciones en statementList1 (la cláusula try). Si statementList1 finaliza sin generar excepciones, se ejecuta statementList2 (la cláusula finally). Si se produce una excepción durante la ejecución de statementList1, el control se transfiere a statementList2; Una vez que statementList2 termina de ejecutarse, la excepción se vuelve a generar. Si una llamada al procedimiento Salir, Pausa o Continuar hace que el control se salga de statementList1, statementList2 se ejecuta automáticamente. Por lo tanto, la cláusula finally se ejecuta siempre, independientemente de cómo finalice la cláusula try.

+0

+1 para listar esas condiciones cuando la cláusula finally no se ejecuta. –

+0

Te perdiste 'Halt'. –

+0

@MrLister No, no lo hice. Lee nuevamente el primer párrafo. –

6

En aras de la exhaustividad - finalmente bloquear se no ejecutar si el proceso o subproceso en ejecución el bloque try..finally se termina con TerminateProcess/TerminateThread.

Por ejemplo, finalmente el bloqueo no se ejecutará en el código siguiente.

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

¿Eché de menos eso en mi respuesta? Tal vez debería haber dicho terminar * thread * anormalmente en vez de programar. –

+0

Tienes razón, dijiste eso. Siéntase libre de combinar mi ejemplo en su respuesta, luego eliminaré el mío. – gabr

+2

Edité mi texto para hacerlo un poco más completo. Su respuesta cubre ese aspecto particular en profundidad y creo que fusionar su ejemplo en mi respuesta restaría valor al punto principal que es la cita de documentación. Gracias y +1. –

Cuestiones relacionadas