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;
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;
Tak, finally
bloki zawsze wykonać, nawet jeśli nazywają Exit
gdzieś. Nie byłyby wiele warte, gdyby nie zostały wykonane.
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.
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.
+1 dla wymieniania tych warunków, gdy klauzula finally nie jest wykonywana. –
Tęskniłeś za "wstrzymaniem". –
@MrLister Nie, nie zrobiłem. Przeczytaj ponownie pierwszy akapit. –
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;
Czy tęskniłem za tym w mojej odpowiedzi? Może powinienem powiedzieć, że zamiast * programu * przerywam * wątek? –
Masz rację, tak to powiedziałeś. Nie krępuj się, łącząc mój przykład z odpowiedzią, a potem usunę mój. – gabr
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. –
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