Share via


Ausnahmen: Der try...finally-Ausdruck (F#)

Mit dem try...finally-Ausdruck können Sie Bereinigungscode ausführen, auch wenn ein Codeblock eine Ausnahme auslöst.

try
   expression1
finally
   expression2

Hinweise

Mit dem try...finally-Ausdruck kann der Code in expression2 in der vorangehenden Syntax unabhängig davon ausgeführt werden, ob während der Ausführung von expression1 eine Ausnahme generiert wird.

Der Typ von expression2 wirkt sich nicht auf den Wert des gesamten Ausdrucks aus. Wenn keine Ausnahme auftritt, ist der letzte Wert in expression1 der zurückgegebene Typ. Wenn eine Ausnahme auftritt, wird kein Wert zurückgegeben, und die Ablaufsteuerung wechselt zum nächsten entsprechenden Ausnahmehandler aufwärts in der Aufrufliste. Wenn kein Ausnahmehandler gefunden wird, wird das Programm beendet. Vor dem Ausführen des Codes in einem entsprechenden Handler oder dem Beenden des Programms wird der Code in der finally-Verzweigung ausgeführt.

Im folgenden Code wird die Verwendung des try...finally-Ausdrucks veranschaulicht.

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

Die Ausgabe an die Konsole lautet wie folgt.

Closing stream
Exception handled.

Wie aus der Ausgabe ersichtlich, wurde der Stream geschlossen, bevor die äußere Ausnahme behandelt wurde, und die Datei test.txt enthält den Text test1. Dies bedeutet, dass die Puffer geleert und auf einen Datenträger geschrieben wurden, obwohl durch die Ausnahme die Steuerung an den Handler für die äußere Ausnahme übergeben wurde.

Beachten Sie, dass das try...with-Konstrukt und das try...finally-Konstrukt zwei verschiedene Konstrukte sind. Wenn der Code sowohl einen with-Block als auch einen finally-Block erfordert, müssen Sie daher die beiden Konstrukte schachteln, wie im folgenden Codebeispiel.

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

Im Kontext von Berechnungsausdrücken, einschließlich Sequenzausdrücken und asynchronen Workflows, können try...finally-Ausdrücke über eine benutzerdefinierte Implementierung verfügen. Weitere Informationen finden Sie unter Berechnungsausdrücke (F#).

Siehe auch

Referenz

Ausnahmen: Der try...with-Ausdruck (F#)

Weitere Ressourcen

Ausnahmebehandlung (F#)