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.