2011-12-23 12 views
17

Czy ostatecznie zostanie wykonany blok? jeśli przekażę wyjście; ?Czy instrukcje w bloku finally nadal są wykonywane w tym kodzie?

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

marginesie: 'natomiast prawda zrobić spróbować wyjścia; w końcu Kontynuuj; end; 'nie skompiluje się - patrz [Zabawa z nieskończonymi pętlami w Delphi i Javie] (http://mikejustin.wordpress.com/2008/07/13/fun-with-infinite-loops-in-delphi-and- java /) – mjn

Odpowiedz

24

Tak, finally bloki zawsze wykonać, nawet jeśli nazywają Exit gdzieś. Nie byłyby wiele warte, gdyby nie zostały wykonane.

10

Szybka aplikacja testowa mogła szybko odpowiedzieć na to pytanie.

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

klauzula finally zawsze będą wykonywane, chyba że wątek wykonujący wchodzi non-kończące pętlę, bloki na czas nieokreślony lub jest nieprawidłowo zakończone, podczas wykonywania klauzuli spróbować.

Stosowne documentation Zjednoczone (moje podkreślenie):

Składnia try ... finally jest

try 
    statementList1 
finally 
    statementList2 
end 

gdzie każdy statementList jest ciągiem wypowiedzi oddzielonych średnikami.

Instrukcja try ... finally wykonuje instrukcji w statementList1 (klauzula try). Jeśli instrukcjaList1 kończy się bez zgłaszania wyjątków, wykonywana jest instrukcja statementList2 (klauzula finally). Jeśli podczas wykonywania instrukcji statementList1 zostanie zgłoszony wyjątek, to kontrola zostanie przeniesiona do instrukcji statementList2; Po zakończeniu instrukcji statementList2 wyjątek zostanie ponownie podniesiony. Jeśli wywołanie procedury Zakończ, Przerwij lub Kontynuuj powoduje, że kontrola opuszcza zestawienieLista1, instrukcjaList2 jest wykonywana automatycznie. W ten sposób klauzula finally jest zawsze wykonywana, niezależnie od tego, jak kończy się klauzula try.

+0

+1 dla wymieniania tych warunków, gdy klauzula finally nie jest wykonywana. –

+0

Tęskniłeś za "wstrzymaniem". –

+0

@MrLister Nie, nie zrobiłem. Przeczytaj ponownie pierwszy akapit. –

6

Dla kompletności - wreszcie zablokowanie zostanie nie wykonać, jeśli proces lub wątku wykonania bloku try..finally jest zakończony TerminateProcess/TerminateThread.

Na przykład, w końcu blok nie zostanie wykonany w poniższym kodzie.

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

Czy tęskniłem za tym w mojej odpowiedzi? Może powinienem powiedzieć, że zamiast * programu * przerywam * wątek? –

+0

Masz rację, tak to powiedziałeś. Nie krępuj się, łącząc mój przykład z odpowiedzią, a potem usunę mój. – gabr

+2

Edytowałem mój tekst, aby był bardziej kompletny. Twoja odpowiedź obejmuje dokładnie ten aspekt i myślę, że połączenie twojego przykładu z moją odpowiedzią umniejszyłoby główny punkt, którym jest cytat z dokumentacji. Dzięki i +1. –

Powiązane problemy