Wyjątki: try...finally — Wyrażenie
Wyrażenie try...finally
umożliwia wykonywanie kodu oczyszczania, nawet jeśli blok kodu zgłasza wyjątek.
Składnia
try
expression1
finally
expression2
Uwagi
Wyrażenie try...finally
może służyć do wykonywania kodu w wyrażeniu2 w poprzedniej składni niezależnie od tego, czy wyjątek jest generowany podczas wykonywania wyrażenia1.
Typ wyrażenia2 nie przyczynia się do wartości całego wyrażenia; typ zwracany, gdy wyjątek nie występuje, jest ostatnią wartością w wyrażeniu1. W przypadku wystąpienia wyjątku żadna wartość nie jest zwracana, a przepływ transferów kontrolek do następnego zgodnego programu obsługi wyjątków w górę stosu wywołań. Jeśli program obsługi wyjątków nie zostanie znaleziony, program zakończy działanie. Przed wykonaniem kodu w zgodnej procedurze obsługi lub zakończeniu programu zostanie wykonany kod w finally
gałęzi.
Poniższy kod demonstruje użycie try...finally
wyrażenia.
let divide x y =
let stream : System.IO.FileStream = System.IO.File.Create("test.txt")
let writer : System.IO.StreamWriter = new System.IO.StreamWriter(stream)
try
writer.WriteLine("test1")
Some( x / y )
finally
writer.Flush()
printfn "Closing stream"
stream.Close()
let result =
try
divide 100 0
with
| :? System.DivideByZeroException -> printfn "Exception handled."; None
Dane wyjściowe konsoli są następujące.
Closing stream
Exception handled.
Jak widać z danych wyjściowych, strumień został zamknięty przed obsłużonym wyjątkiem zewnętrznym, a plik test.txt
zawiera tekst test1
, który wskazuje, że bufory zostały opróżnione i zapisane na dysku, mimo że wyjątek został przeniesiony do zewnętrznej procedury obsługi wyjątków.
Należy pamiętać, że try...with
konstrukcja jest oddzielną konstrukcją od try...finally
konstrukcji. W związku z tym, jeśli kod wymaga zarówno with
bloku, jak i finally
bloku, musisz zagnieżdżać dwie konstrukcje, jak w poniższym przykładzie kodu.
exception InnerError of string
exception OuterError of string
let function1 x y =
try
try
if x = y then raise (InnerError("inner"))
else raise (OuterError("outer"))
with
| InnerError(str) -> printfn "Error1 %s" str
finally
printfn "Always print this."
let function2 x y =
try
function1 x y
with
| OuterError(str) -> printfn "Error2 %s" str
function2 100 100
function2 100 10
W kontekście wyrażeń obliczeniowych, w tym wyrażeń sekwencji i wyrażeń asynchronicznych, spróbuj... wreszcie wyrażenia mogą mieć implementację niestandardową. Aby uzyskać więcej informacji, zobacz Wyrażenia obliczeniowe.