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.

Vedi anche