Выражения: выражение 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
В контексте вычислительных выражений, включая выражения последовательности и асинхронные выражения, попробуйте... Наконец , выражения могут иметь настраиваемую реализацию. Дополнительные сведения см. в разделе "Выражения вычислений".