Výjimky: Výraz try...finally

Výraz try...finally umožňuje spustit kód čištění, i když blok kódu vyvolá výjimku.

Syntaxe

try
    expression1
finally
    expression2

Poznámky

Výraz try...finally lze použít ke spuštění kódu ve výrazu 2 v předchozí syntaxi bez ohledu na to, jestli se během provádění výrazu 1 vygeneruje výjimka.

Typ výrazu2 nepřispívá k hodnotě celého výrazu; typ vrácený v případě, že nedojde k výjimce, je poslední hodnotou ve výrazu1. Pokud dojde k výjimce, nevrátí se žádná hodnota a tok řízení se přenese do další odpovídající obslužné rutiny výjimky do zásobníku volání. Pokud se nenajde žádná obslužná rutina výjimky, program se ukončí. Před spuštěním kódu v odpovídající obslužné rutině nebo ukončením programu se kód ve finally větvi spustí.

Následující kód ukazuje použití výrazu 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

Výstup do konzoly je následující.

Closing stream
Exception handled.

Jak vidíte z výstupu, datový proud byl uzavřen před zpracování vnější výjimky a soubor test.txt obsahuje text test1, který označuje, že vyrovnávací paměti byly vyprázdněny a zapsány na disk, i když výjimka přenesla ovládací prvek do vnější obslužné rutiny výjimky.

Všimněte si, že try...with konstruktor je samostatný konstruktor od konstruktoru try...finally . Proto pokud váš kód vyžaduje with blok i finally blok, musíte vnořit tyto dva konstruktory, jako v následujícím příkladu kódu.

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

V kontextu výpočetních výrazů, včetně sekvenčních výrazů a asynchronních výrazů, zkuste... výrazy finally mohou mít vlastní implementaci. Další informace naleznete v tématu Výpočetní výrazy.

Viz také