Compartilhar via


Exceções: a tentativa... expressão finally

A try...finally expressão permite que você execute o código de limpeza mesmo que um bloco de código gere uma exceção.

Sintaxe

try
    expression1
finally
    expression2

Observações

A try...finally expressão pode ser usada para executar o código na expressão2 na sintaxe anterior, independentemente de uma exceção ser gerada durante a execução da expressão1.

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 até a pilha de chamadas. Se nenhum manipulador de exceção for encontrado, o programa será encerrado. Antes que o código em um manipulador de correspondência seja executado ou o programa seja encerrado, o código no finally branch será 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 da exceção externa ser tratada e o arquivo test.txt contém o texto test1, que indica que os buffers foram liberados e gravados em disco, mesmo que a exceção tenha sido transferida para o manipulador de exceção externa.

Observe que o try...with constructo é um constructo separado do try...finally constructo. Portanto, se o código exigir um with bloco e um finally bloco, você precisará aninhar os dois constructos, 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 de computação, incluindo expressões de sequência e expressões assíncronas, tente... por fim, as expressões podem ter uma implementação personalizada. Para obter mais informações, consulte Expressões de Computação.

Consulte também