Выражения: выражение try...finally

Выражение try...finally позволяет выполнять код очистки, даже если блок кода создает исключение.

Синтаксис

try
    expression1
finally
    expression2

Замечания

Выражение try...finally можно использовать для выполнения кода в выражении2 в предыдущем синтаксисе независимо от того, создается ли исключение во время выполнения выражения1.

Тип выражения2 не способствует значению всего выражения; тип, возвращаемый, если исключение не происходит, является последним значением в выражении1. При возникновении исключения возвращаемое значение не возвращается, а поток управления передается следующему обработчику исключений в стек вызовов. Если обработчик исключений не найден, программа завершает работу. Перед выполнением кода в соответствующем обработчике или завершением программы выполняется код в finally ветви.

В следующем коде показано использование 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

Выходные данные консоли приведены следующим образом.

Closing stream
Exception handled.

Как видно из выходных данных, поток был закрыт до обработки внешнего исключения, а файл test.txt содержит текст test1, который указывает, что буферы были промыты и записаны на диск, даже если исключение передано в внешний обработчик исключений.

Обратите внимание, что конструкция try...with является отдельной конструкцией от try...finally конструкции. Таким образом, если для кода требуется как блок, так with и finally блок, необходимо вложить две конструкции, как показано в следующем примере кода.

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

В контексте вычислительных выражений, включая выражения последовательности и асинхронные выражения, попробуйте... Наконец , выражения могут иметь настраиваемую реализацию. Дополнительные сведения см. в разделе "Выражения вычислений".

См. также