2015-02-06 3 views
2

Следующий код генерирует исключение ObjectDisposedException при чтении из файла. Кажется, что BinaryReader выходит за пределы области до того, как будет перечислина вся последовательность. Каков правильный способ безопасного совершения этого звонка без утечки читателя? Я предпочитаю не выполнять управление потоками в коде верхнего уровня - идеально, что скрывается с учетом пути к файлу.Правильное удаление потока в F #

В этом коде 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 
+5

Оцените последовательность с нетерпением, например. превратите его в 'list' или' array', прежде чем возвращать его. Альтернативный, положите 'use' непосредственно внутри выражения последовательности. – ildjarn

ответ

3

Как было отмечено в комментарии iljdarn, положив use внутри выражение последовательности фиксирует это. Это работает, потому что построитель выражений последовательности определяет свою собственную семантику для ключевого слова use, чтобы поддерживать удаление в соответствующее время. Таким образом, если вы измените эту функцию на

let readBinaryEdges fn = 
    seq { use br = new BinaryReader(File.OpenRead(fn)) 
      yield! readEdges br } 

считыватель будет расположен с последовательностью.