F#: Disposing of resources that are inside a closure?
Suppose I create a closure over a resource such as a StreamWriter:
let currentdir = Directory.GetCurrentDirectory()
let testfile = sprintf "%s\\%s" c开发者_如何转开发urrentdir "closuretest.txt"
let getwriter() =
let writer = new StreamWriter(testfile, false)
(fun() -> writer.Write "test")
Is there a way to close the StreamWriter when I'm done with the closure? Or do I need to replace the closure with a wrapper object that has a Write() method and a Dispose() method? (This is of course a trivialized example.) Thanks all.
Yes, you should to replace the closure with an IDisposable
object with a method and a Dispose()
. (Alternatively, return a tuple of closures, the second of which calls Close()
or whatnot, and leave it to the caller like that.)
(While you're at it, System.IO.Path.Combine()
should be used, rather than glueing together filenames with string formatting.)
I sometimes do:
let getwriter() =
let writer = new StreamWriter(testfile, false)
(fun() ->
use writer = writer
writer.Write "test")
IDisposable
is about deterministically, i.e. explicitly releasing resources. Thus if the closure doesn't somehow provide a disposing functionality by itself, the resource cannot be release deterministically any more.
As Brian pointed out, this can be more or less explicit, though implementing IDisposable
is preferrable as use
+ IDisposable automatically takes care of releasing resources in case of exceptions.
However, sometimes it's sufficient to completely hide the disposable resource and get a closure of what's to be done instead.
let getWriter body =
use writer = new StreamWriter(testfile, false)
body(writer)
// ...
getWriter (fun writer -> writer.Write "test")
精彩评论