Io 正确处理F中的流#

Io 正确处理F中的流#,io,f#,idisposable,Io,F#,Idisposable,以下代码在读取文件时引发ObjectDisposedException。在枚举整个序列之前,BinaryReader似乎已超出范围。什么是安全地拨打此电话而不泄漏读卡器的正确方法?我不喜欢在顶级代码中进行流管理——理想情况下,在给定文件路径的情况下,流管理是隐藏的 在这段代码中,Edge.ReadBinary完成了从二进制流反序列化边缘的明显任务。在我的代码中,文件夹做了一些更复杂的事情,但为了可读性,我在这里对其进行了简化 let rec readEdges (br:BinaryReader)

以下代码在读取文件时引发ObjectDisposedException。在枚举整个序列之前,BinaryReader似乎已超出范围。什么是安全地拨打此电话而不泄漏读卡器的正确方法?我不喜欢在顶级代码中进行流管理——理想情况下,在给定文件路径的情况下,流管理是隐藏的

在这段代码中,Edge.ReadBinary完成了从二进制流反序列化边缘的明显任务。在我的代码中,文件夹做了一些更复杂的事情,但为了可读性,我在这里对其进行了简化

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 }

读取器将处理序列。

急切地评估序列,例如,在返回序列之前将其转换为
列表
数组
。或者,将
use
直接放在序列表达式中。