在 F# 中正确处理流
Properly disposing a stream in F#
以下代码在读取文件时抛出 ObjectDisposedException。在枚举整个序列之前,BinaryReader 似乎超出了范围。在不泄漏 reader 的情况下安全地进行此调用的正确方法是什么?我宁愿不必在顶级代码中进行流管理——理想情况下,它是隐藏在给定文件路径的地方。
在此代码中,Edge.ReadBinary 执行从二进制流中反序列化 Edge 的明显任务。在我的代码中,该文件夹做了一些更复杂的事情,但为了便于阅读,我在这里对其进行了简化。
let rec readEdges (br:BinaryReader) =
seq {
match Edge.ReadBinary br with
| None -> yield! Seq.empty
| Some(e) -> yield e; yield! readEdges br
}
let readBinaryEdges fn =
use br=new BinaryReader(File.OpenRead(fn))
readEdges br
let sampled=readBinaryEdges fn |> Seq.fold (fun result l -> l::result) list.Empty
正如 iljdarn 的评论中所指出的,将 use
放在序列表达式中可以解决此问题。这是有效的,因为序列表达式构建器为 use
关键字定义了自己的语义,以支持在适当的时间进行处置。因此,如果您将函数更改为
let readBinaryEdges fn =
seq { use br = new BinaryReader(File.OpenRead(fn))
yield! readEdges br }
reader 将与序列一起处理。
以下代码在读取文件时抛出 ObjectDisposedException。在枚举整个序列之前,BinaryReader 似乎超出了范围。在不泄漏 reader 的情况下安全地进行此调用的正确方法是什么?我宁愿不必在顶级代码中进行流管理——理想情况下,它是隐藏在给定文件路径的地方。
在此代码中,Edge.ReadBinary 执行从二进制流中反序列化 Edge 的明显任务。在我的代码中,该文件夹做了一些更复杂的事情,但为了便于阅读,我在这里对其进行了简化。
let rec readEdges (br:BinaryReader) =
seq {
match Edge.ReadBinary br with
| None -> yield! Seq.empty
| Some(e) -> yield e; yield! readEdges br
}
let readBinaryEdges fn =
use br=new BinaryReader(File.OpenRead(fn))
readEdges br
let sampled=readBinaryEdges fn |> Seq.fold (fun result l -> l::result) list.Empty
正如 iljdarn 的评论中所指出的,将 use
放在序列表达式中可以解决此问题。这是有效的,因为序列表达式构建器为 use
关键字定义了自己的语义,以支持在适当的时间进行处置。因此,如果您将函数更改为
let readBinaryEdges fn =
seq { use br = new BinaryReader(File.OpenRead(fn))
yield! readEdges br }
reader 将与序列一起处理。