Udostępnij za pośrednictwem


Wyjątki: try...finally — Wyrażenie

Wyrażenie try...finally umożliwia wykonywanie kodu oczyszczania, nawet jeśli blok kodu zgłasza wyjątek.

Składnia

try
    expression1
finally
    expression2

Uwagi

Wyrażenie try...finally może służyć do wykonywania kodu w wyrażeniu2 w poprzedniej składni niezależnie od tego, czy wyjątek jest generowany podczas wykonywania wyrażenia1.

Typ wyrażenia2 nie przyczynia się do wartości całego wyrażenia; typ zwracany, gdy wyjątek nie występuje, jest ostatnią wartością w wyrażeniu1. W przypadku wystąpienia wyjątku żadna wartość nie jest zwracana, a przepływ transferów kontrolek do następnego zgodnego programu obsługi wyjątków w górę stosu wywołań. Jeśli program obsługi wyjątków nie zostanie znaleziony, program zakończy działanie. Przed wykonaniem kodu w zgodnej procedurze obsługi lub zakończeniu programu zostanie wykonany kod w finally gałęzi.

Poniższy kod demonstruje użycie try...finally wyrażenia.

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

Dane wyjściowe konsoli są następujące.

Closing stream
Exception handled.

Jak widać z danych wyjściowych, strumień został zamknięty przed obsłużonym wyjątkiem zewnętrznym, a plik test.txt zawiera tekst test1, który wskazuje, że bufory zostały opróżnione i zapisane na dysku, mimo że wyjątek został przeniesiony do zewnętrznej procedury obsługi wyjątków.

Należy pamiętać, że try...with konstrukcja jest oddzielną konstrukcją od try...finally konstrukcji. W związku z tym, jeśli kod wymaga zarówno with bloku, jak i finally bloku, musisz zagnieżdżać dwie konstrukcje, jak w poniższym przykładzie kodu.

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

W kontekście wyrażeń obliczeniowych, w tym wyrażeń sekwencji i wyrażeń asynchronicznych, spróbuj... wreszcie wyrażenia mogą mieć implementację niestandardową. Aby uzyskać więcej informacji, zobacz Wyrażenia obliczeniowe.

Zobacz też