Uitzonderingen: Het proberen... eindelijk expressie
Met de try...finally
expressie kunt u opschoningscode uitvoeren, zelfs als een codeblok een uitzondering genereert.
Syntaxis
try
expression1
finally
expression2
Opmerkingen
De try...finally
expressie kan worden gebruikt om de code uit te voeren in expressie2 in de voorgaande syntaxis, ongeacht of er een uitzondering wordt gegenereerd tijdens de uitvoering van expressie1.
Het type expressie2 draagt niet bij aan de waarde van de hele expressie. Het type dat wordt geretourneerd wanneer er geen uitzondering optreedt, is de laatste waarde in expressie1. Wanneer er een uitzondering optreedt, wordt er geen waarde geretourneerd en wordt de stroom van besturingselementen overgedragen naar de volgende overeenkomende uitzonderingshandler voor de aanroepstack. Als er geen uitzonderingshandler wordt gevonden, wordt het programma beƫindigd. Voordat de code in een overeenkomende handler wordt uitgevoerd of het programma wordt beƫindigd, wordt de code in de finally
vertakking uitgevoerd.
De volgende code laat het gebruik van de try...finally
expressie zien.
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
De uitvoer naar de console is als volgt.
Closing stream
Exception handled.
Zoals u in de uitvoer kunt zien, is de stroom gesloten voordat de buitenste uitzondering werd verwerkt en bevat het bestand test.txt
de tekst test1
, die aangeeft dat de buffers zijn leeggemaakt en naar schijf zijn geschreven, ook al is het besturingselement van de uitzondering overgedragen naar de buitenste uitzonderingshandler.
Houd er rekening mee dat de try...with
constructie een afzonderlijke constructie is van de try...finally
constructie. Als voor uw code zowel een blok als with
een finally
blok is vereist, moet u de twee constructies nesten, zoals in het volgende codevoorbeeld.
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
Probeer het in de context van berekeningsexpressies, inclusief reeksexpressies en asynchrone expressies, ... ten slotte kunnen expressies een aangepaste implementatie hebben. Zie Berekeningsexpressies voor meer informatie.