Condividi tramite


Eccezioni: espressione try...finally (F#)

L'espressione try...finally consente di eseguire codice di pulizia anche se un blocco di codice genera un'eccezione.

try
   expression1
finally
   expression2

Note

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 non si verifica un'eccezione è l'ultimo valore in expression1. Quando si verifica un'eccezione, non viene restituito alcun valore e il flusso di controllo passa al gestore di eccezioni corrispondente successivo più in alto nello stack di chiamate. Se non viene trovato alcun gestore di eccezioni, il programma termina. Prima che venga eseguito il codice in un gestore corrispondente o che il programma termini, viene eseguito il codice nel ramo finally.

Nel codice seguente viene illustrato l'utilizzo 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

Di seguito è riportato l'output nella console.

Closing stream
Exception handled.

Come è possibile vedere dall'output, il flusso è stato chiuso prima che venisse gestita l'eccezione esterna e il file test.txt contiene il testo test1 che indica che i buffer sono stati scaricati e scritti nel disco anche se l'eccezione ha trasferito il controllo al gestore di eccezioni esterno.

Si noti che il costrutto try...with è distinto dal costrutto try...finally. Se pertanto nel codice sono necessari sia un blocco with che un blocco finally, sarà 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 di espressioni di calcolo, incluse le espressioni di sequenza e i flussi di lavoro asincroni, le espressioni try...finally possono presentare un'implementazione personalizzata. Per ulteriori informazioni, vedere Espressioni di calcolo (F#).

Vedere anche

Riferimenti

Eccezioni: espressione try...with (F#)

Altre risorse

Gestione delle eccezioni (F#)