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.

Zie ook