Exceções: A tentativa... finalmente Expressão
A try...finally
expressão permite que você execute código de limpeza mesmo se um bloco de código lançar uma exceção.
Sintaxe
try
expression1
finally
expression2
Observações
A try...finally
expressão pode ser usada para executar o código em expression2 na sintaxe anterior, independentemente de uma exceção ser gerada durante a execução de expression1.
O tipo de expressão2 não contribui para o valor da expressão inteira, o tipo retornado quando uma exceção não ocorre é o último valor na expressão1. Quando uma exceção ocorre, nenhum valor é retornado e o fluxo de controle é transferido para o próximo manipulador de exceção correspondente na pilha de chamadas. Se nenhum manipulador de exceção for encontrado, o programa será encerrado. Antes que o código em um manipulador correspondente seja executado ou o programa seja encerrado, o finally
código na ramificação é executado.
O código a seguir demonstra o uso da try...finally
expressão.
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
A saída para o console é a seguinte.
Closing stream
Exception handled.
Como você pode ver na saída, o fluxo foi fechado antes que a exceção externa fosse manipulada, e o arquivo test.txt
contém o texto test1
, o que indica que os buffers foram liberados e gravados no disco mesmo que a exceção tenha transferido o controle para o manipulador de exceção externo.
Observe que a try...with
construção é uma construção separada da try...finally
construção. Portanto, se seu código requer um with
bloco e um finally
bloco, você tem que aninhar as duas construções, como no exemplo de código a seguir.
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
No contexto de expressões computacionais, incluindo expressões de sequência e expressões assíncronas, tente... Finalmente, as expressões podem ter uma implementação personalizada. Para obter mais informações, consulte Expressões de computação.