Blok Try...Finally


Czasami istnieje potrzeba zapewnienia dokończenia wykonania pewnych operacji, niezależnie od tego, czy operacja zostanie przerwana przez zgłoszony wyjątek. Przykładowo, gdy procedura przejmuje kontrolę nad pewnymi zasobami, często istotne jest, żeby zwolnić te zasoby, niezależnie od tego czy wykonanie procedury kończy się normalnie czy też nie. W takich sytuacjach, można użyć instrukcji try...finally.

Następujący przykład pokazuje, jak kod otwierający i przetwarzający plik może zapewnić zamknięcie pliku, nawet pomimo błędów jakie mogą się zdarzyć podczas wykonania procedury.

Reset(F);
try
 ...  // obróbka pliku F
finally
  CloseFile(F);
end;

Składnia instrukcji try...finally:

try statementList1 finally statementList2 end
gdzie statementList1 i statementList2 są sekwencjami instrukcji oddzielonych średnikami. Instrukcja try...finally wykonuje instrukcje w statementList1 (w obrębie klauzuli try). Jeśli statementList1 kończy się bez zgłoszenia wyjątku, wykonywana jest statementList2 (klauzula finally). Jeśli podczas wykonywania statementList1, zostanie zgłoszony wyjątek, sterowanie przekazywane jest do statementList2; kiedy statementList2 wykona się do końca, wykonywane jest powtórne zgłoszenie wyjątku. Jeśli wywołanie procedury Exit, Break, lub Continue spowoduje przeniesienie sterowania poza statementList1, automatycznie wykonywana jest statementList2. Tak więc, klauzula finally wykonywana jest zawsze, niezależnie od sposobu przerwania instrukcji try...finally.

Jeśli w klauzuli finally zostanie zgłoszony i nie obsłużony wyjątek, jest on propagowany poza instrukcję try...finally, a wszystkie wyjątki już zgłoszone w klauzuli try są tracone. Zatem klauzula finally powinna obsługiwać wszystkie lokalnie zgłoszone wyjątki, tak by nie przeszkadzać w propagacji innych wyjątków.