例如:
let test () =
async {
try
do! someting ()
finally
do! sometingElse ()
}
你不能在最后得到do!
你从编译器得到消息“你只能在计算表达式中使用do!”但它仍然在那里。
我知道如何解决这个问题,但我想了解编译器限制这种情况的原因。
好了一些fiddeling后我觉得它像这样沮丧:(我很高兴我们可以写cexprs)
从:
async {
try
do! someting ()
do! sometingElse ()
finally
printfn "finally"
}
为:
async.TryFinally(
async.Bind(
someting(), (fun () ->
async.Bind(sometingElse (), (fun () ->
async.Zero())))), (fun () -> printfn "finally")) |> ignore
我知道TryFinally
的第二部分不支持cexpr
。
答案 0 :(得分:7)
正如问题中已经讨论过的那样,try-finally
子句的finally
表达式根本不受支持(在F#3.1中)。但是,很容易实现具有这种行为的功能。以下是一个示例实现:
let tryFinally (body: Async<'x>) (finalize: Async<unit>) : Async<'x> = async {
let! result = Async.Catch body
do! finalize
return match result with
| Choice1Of2 value -> value
| Choice2Of2 exn -> raise exn
}