Eccezioni: espressione try...finally
L'espressione try...finally
consente di eseguire codice di pulizia anche se un blocco di codice genera un'eccezione.
Sintassi
try
expression1
finally
expression2
Osservazioni:
L'espressione try...finally
può essere utilizzata per eseguire il codice in expression2 nella sintassi precedente, indipendentemente dal fatto che venga generata un'eccezione durante l'esecuzione di expression1.
Il tipo di expression2 non contribuisce al valore dell'intera espressione. Il tipo restituito quando un'eccezione non si verifica è l'ultimo valore in expression1. Quando si verifica un'eccezione, non viene restituito alcun valore e il flusso di controlli trasferisce al gestore eccezioni corrispondente successivo fino allo stack di chiamate. Se non viene trovato alcun gestore eccezioni, il programma termina. Prima di eseguire il codice in un gestore corrispondente o terminare il programma, viene eseguito il finally
codice nel ramo .
Il codice seguente illustra l'uso dell'espressione try...finally
.
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
L'output della console è il seguente.
Closing stream
Exception handled.
Come si può notare dall'output, il flusso è stato chiuso prima della gestione dell'eccezione esterna e il file test.txt
contiene il testo test1
, che indica che i buffer sono stati scaricati e scritti su disco anche se il controllo dell'eccezione è stato trasferito al gestore eccezioni esterno.
Si noti che il try...with
costrutto è un costrutto separato dal try...finally
costrutto. Pertanto, se il codice richiede sia un with
blocco che un finally
blocco, è necessario annidare i due costrutti, come nell'esempio di codice seguente.
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
Nel contesto delle espressioni di calcolo, incluse le espressioni di sequenza e le espressioni asincrone, provare... le espressioni finally possono avere un'implementazione personalizzata. Per altre informazioni, vedere Espressioni di calcolo.