如何使用序列表达式按需从Webstream返回行

时间:2010-11-15 14:55:50

标签: f#

这个功能很好,但它不能达到我想要的效果,但我已经使用它来确保对象的使用是正常的:

   let getStreamData_ok (uri:string) =
        let request = WebRequest.Create uri 
        use response = request.GetResponse()
        use stream = response.GetResponseStream()
        use reader = new StreamReader(stream)
        while not reader.EndOfStream do 
            ignore <| reader.ReadLine() 

我想连接到一个流,并根据需要一次将文件拉下一行。这个功能不起作用,我尝试将各种线路移入和移出序列表达式而没有任何成功:

let getStreamData_OnDemand (uri:string) =
    let request = WebRequest.Create uri 
    use response = request.GetResponse()

    seq { 
        use stream = response.GetResponseStream()
        use reader = new StreamReader(stream)
        while not reader.EndOfStream do 
            yield reader.ReadLine() 
    } 

使用代码:

let lines = getStreamData_OnDemand("http://stackoverflow.com/")
for line in lines do
    ignore line

谢谢

1 个答案:

答案 0 :(得分:5)

这应该有效:

let getStreamData_OnDemand (uri:string) = seq {
    let request = WebRequest.Create uri  
    use response = request.GetResponse() 
    use stream = response.GetResponseStream() 
    use reader = new StreamReader(stream) 
    while not reader.EndOfStream do  
        yield reader.ReadLine() }  

与第二个代码段(使用序列表达式的代码片段)相比的关键区别在于所有都是在序列表达式中完成的。最重要的是,use response = ...行也包含在序列表达式中。

这是必不可少的,因为在这种情况下use意味着只有在完成序列的迭代之后才会处置response。在第二个代码段中,在从返回的序列中读取任何内容之前,您将处置response

在原始片段中,它会在getStreamData_OnDemand返回后处理,但是在您开始迭代序列之前就已经处理了 - 所以当您开始迭代序列时,它已经被处理掉了!