【问题标题】:F#: Disposing of resources that are inside a closure?F#:处置闭包内的资源?
【发布时间】:2011-05-24 11:38:45
【问题描述】:

假设我在 StreamWriter 等资源上创建了一个闭包:

let currentdir = Directory.GetCurrentDirectory()
let testfile = sprintf "%s\\%s" currentdir "closuretest.txt"

let getwriter() =
    let writer = new StreamWriter(testfile, false)
    (fun() -> writer.Write "test")

当我完成关闭后,有没有办法关闭 StreamWriter?还是我需要用具有 Write() 方法和 Dispose() 方法的包装器对象替换闭包? (这当然是一个简单的例子。)谢谢大家。

【问题讨论】:

    标签: f# closures dispose


    【解决方案1】:

    IDisposable 是关于确定性,即明确释放资源。因此,如果闭包本身不能以某种方式提供处置功能,则无法再确定性地释放资源。

    正如 Brian 指出的那样,这可能或多或少是明确的,但最好实现 IDisposable,因为 use + IDisposable 会自动负责在发生异常时释放资源。

    但是,有时完全隐藏一次性资源并关闭要完成的操作就足够了。

    let getWriter body = 
        use writer = new StreamWriter(testfile, false)
        body(writer)
    
    // ...
    
    getWriter (fun writer -> writer.Write "test")
    

    【讨论】:

    • 非常感谢您的回复达里奥。据我所知,闭包仅表示为另一个 .NET 对象。我想知道在某个时候我们是否会找到一种方法来向它添加 finalize/dispose 代码。
    【解决方案2】:

    我有时会这样做:

    let getwriter() =
      let writer = new StreamWriter(testfile, false)
      (fun() ->
        use writer = writer
        writer.Write "test")
    

    【讨论】:

    • 非常感谢 Harrop 博士的回复。看起来它将打开文件的工作保留在闭包之外,但在闭包退出时仍会关闭文件。我将来会使用它。
    【解决方案3】:

    是的,你应该用 IDisposable 对象和方法和 Dispose() 替换闭包。 (或者,返回一个闭包元组,其中第二个调用Close() 或诸如此类,然后将其留给调用者。)

    (当您使用它时,应该使用System.IO.Path.Combine(),而不是将文件名与字符串格式粘合在一起。)

    【讨论】:

    • 非常感谢 Brian 的快速回复。可用的 F# 材料似乎在讨论闭包和资源管理,但不是将两者结合在一起。
    猜你喜欢
    • 2012-01-05
    • 1970-01-01
    • 2012-04-11
    • 1970-01-01
    • 2011-12-25
    • 1970-01-01
    • 2016-12-24
    • 2015-09-06
    • 1970-01-01
    相关资源
    最近更新 更多