例外狀況:try...finally 運算式
try...finally
運算式能讓您執行清理程式碼,即使程式碼區塊擲出例外狀況也一樣。
語法
try
expression1
finally
expression2
備註
不論在 expression1 執行期間是否產生例外狀況,try...finally
運算式都可以用來在上述語法中執行 expression2 中的程式碼。
expression2 的類型不會促成整個運算式的值;未發生例外狀況時所傳回的類型是 expression1 中的最後一個值。 當確實發生例外狀況時,不會傳回任何值,而且控制流程會傳輸到呼叫堆疊中向上的下一個相符的例外狀況處理常式。 如果找不到任何例外狀況處理常式,程式就會終止。 在執行相符的處理常式中的程式碼或程式終止之前,會執行 finally
分支中的程式碼。
下列程式碼示範 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
主控台的輸出如下所示。
Closing stream
Exception handled.
如您在輸出中所見,在處理外部例外狀況之前已關閉串流,而且檔案 test.txt
包含文字 test1
(指出緩衝區已排清並寫入磁碟,即使例外狀況將控制權轉移給例外狀況處理常式也一樣)。
請注意,try...with
建構是與 try...finally
建構不同的建構。 因此,如果您的程式碼需要 with
區塊和 finally
區塊,則您必須內嵌這兩個建構,如下列程式碼範例所示。
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
在計算運算式(包括順序運算式和非同步運算式)的內容中,try...finally 運算式可以有自訂的實作。 如需詳細資訊,請參閱計算運算式。