Dela via


Undantag: Försök... äntligen uttryck

Med try...finally uttrycket kan du köra rensningskod även om ett kodblock utlöser ett undantag.

Syntax

try
    expression1
finally
    expression2

Kommentarer

Uttrycket try...finally kan användas för att köra koden i expression2 i föregående syntax oavsett om ett undantag genereras under körningen av expression1.

Typen av uttryck2 bidrar inte till värdet för hela uttrycket. Den typ som returneras när ett undantag inte inträffar är det sista värdet i expression1. När ett undantag inträffar returneras inget värde och flödet av kontroll överförs till nästa matchande undantagshanterare uppåt i anropsstacken. Om ingen undantagshanterare hittas avslutas programmet. Innan koden i en matchande hanterare körs eller programmet avslutas körs koden i grenen finally .

Följande kod visar hur uttrycket används 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

Utdata till konsolen är följande.

Closing stream
Exception handled.

Som du ser från utdata stängdes strömmen innan det yttre undantaget hanterades och filen test.txt innehåller texten test1, vilket anger att buffertarna tömdes och skrevs till disken trots att undantaget överförde kontrollen till den yttre undantagshanteraren.

Observera att konstruktionen try...with är en separat konstruktion från konstruktionen try...finally . Om koden kräver både ett with block och ett finally block måste du därför kapsla de två konstruktionerna, som i följande kodexempel.

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

När det gäller beräkningsuttryck, inklusive sekvensuttryck och asynkrona uttryck, kan du prova... slutligen kan uttryck ha en anpassad implementering. Mer information finns i Beräkningsuttryck.

Se även