Поделиться через


Выражения: выражение try...finally (F#)

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

try
   expression1
finally
   expression2

Заметки

С помощью выражения try...finally можно выполнить код, указанный в разделе expression2 (см. приведенный выше синтаксис), несмотря на исключение, созданное при выполнении кода из раздела expression1.

Тип выражения expression2 не влияет на значение всего выражения; если исключения не возникло, возвращаемым типом является последнее значение выражения expression1. Если исключение все же возникло, выражение не возвращает никакого значения и управление передается ближайшему соответствующему обработчику исключений в стеке вызова. Если такой обработчик исключений не обнаружен, выполнение программы прекращается. Прежде чем выполняется соответствующий обработчик исключений или прекращается выполнение программы, выполняется код из раздела 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

В контексте вычислительных выражений, включая выражения последовательностей и асинхронные рабочие процессы, выражения try...finally могут иметь настраиваемые реализации. Дополнительные сведения см. в разделе Выражения вычисления (F#).

См. также

Ссылки

Исключения: выражение try...with (F#)

Другие ресурсы

Обработка исключений (F#)