Exceptions : expression try...finally (F#)

L'expression try...finally vous permet d'exécuter du code de nettoyage même si un bloc de code lève une exception.

try
   expression1
finally
   expression2

Notes

L'expression try...finally peut être utilisée pour exécuter le code dans expression2 dans la syntaxe précédente, et ce qu'une exception ait été générée pendant l'exécution d'expression1 ou non.

Le type d'expression2 ne contribue pas à la valeur de l'expression entière ; le type retourné lorsqu'une exception ne se produit pas est la dernière valeur dans expression1. Lorsqu'une exception se produit, aucune valeur n'est retournée et le flux de contrôle est transféré au prochain gestionnaire d'exceptions correspondant en haut de la pile des appels. Si aucun gestionnaire d'exceptions n'est trouvé, le programme se termine. Avant que le code dans un gestionnaire correspondant ne soit exécuté ou que le programme ne se termine, le code dans la branche finally est exécuté.

Le code suivant illustre l'utilisation de l'expression 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

La sortie dans la console est la suivante.

Closing stream
Exception handled.

Comme vous pouvez le voir dans la sortie, le flux est fermé avant la gestion de l'exception externe ; par ailleurs, le fichier test.txt contient le texte test1, ce qui indique que les mémoires tampons ont été vidées et écrites sur le disque bien que l'exception ait transféré le contrôle au gestionnaire d'exceptions externe.

Notez que la construction try...with est une construction séparée de la construction try...finally. Par conséquent, si votre code nécessite à la fois un bloc with et un bloc finally, vous devez imbriquer les deux constructions, comme dans l'exemple de code suivant.

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

Dans le contexte d'expressions de calcul, notamment les expressions de séquence et flux de travail asynchrones, les expressions try...finally peuvent avoir une implémentation personnalisée. Pour plus d'informations, consultez Expressions de calcul (F#).

Voir aussi

Référence

Exceptions : expression try...with (F#)

Autres ressources

Gestion des exceptions (F#)