In F# async workflows, we can define a resource that should be cleaned up with the use keyword.
But how does use interact with return?
For example, given this code:
let createResource = async {
use r = Resource ()
do! operationThatMightThrow r
return r
}
async {
use! r = createResource
printfn "%O" r
}
|> Async.RunSynchronously
Where will the calls to Resource.Dispose happen?
How can I design this so that the r is always cleaned up (even if operationThatMightThrow throws)?
I usually have two solutions.
The first solution is actively capturing the exception, manually disposing the disposable object, and re-throwing the exception:
The second solution is to use a continuation function that will have access to the disposable object before the async returns: