Asynchronous IDisposable如何使用和返回?
在F#Asynchronous IDisposable如何使用和返回?,asynchronous,f#,disposable,Asynchronous,F#,Disposable,在F#async工作流中,我们可以定义一个应该使用use关键字清理的资源 但是use如何与return交互 例如,给定以下代码: let createResource = async { use r = Resource () do! operationThatMightThrow r return r } async { use! r = createResource printfn "%O" r } |> Async.RunSynchronously 对R
async
工作流中,我们可以定义一个应该使用use
关键字清理的资源
但是use
如何与return
交互
例如,给定以下代码:
let createResource = async {
use r = Resource ()
do! operationThatMightThrow r
return r
}
async {
use! r = createResource
printfn "%O" r
}
|> Async.RunSynchronously
对Resource.Dispose
的调用将在哪里发生
我如何设计它,使
r
始终被清除(即使操作可能抛出抛出)?它们将在值从计算表达式返回之前发生,语义上它们将发生在finally
块中。如果要查看生成的using语句的源代码,可以找到它。它有效地生成了一个访问控制的dispose函数,该函数对传入的资源调用dispose()
,然后在finally子句中使用该函数进行异步try finally阻塞。我通常有两种解决方案
第一种解决方案是主动捕获异常,手动处理一次性对象,然后重新抛出异常:
let createResource = async {
let r = new Resource ()
try do! operationThatMightThrow r
with e -> (r :> IDisposable).Dispose(); raise e
return r
}
第二种解决方案是使用一个continuation函数,该函数将在异步返回之前访问一次性对象:
let createResource cont = async {
use r = new Resource ()
do! operationThatMightThrow r
return cont r
}
async {
let! x = createResource (fun r -> printfn "in cont: %O" r)
...
}