递归序列生成

时间:2014-10-05 11:26:17

标签: .net recursion f#

我正在尝试通过递归读取数据源中的数据来生成切片序列。

let rec read stream startFrom (conn : IEventStoreConnection) = 
    seq {
        let size = 10000
        let slice = conn.ReadStreamEventsForwardAsync(stream, startFrom, size, true).Result

        Console.WriteLine("Events in slice: " + slice.Events.Count().ToString())

        if (slice.IsEndOfStream) then
           yield slice
        else
           yield! read stream (startFrom + 1 * size) conn 
    }

let slices = read "stream-name" 0 conn

Console.WriteLine("TOTAL slices in sequence: " + (Seq.length slices).ToString());

我期待序列包含三个项目,但它似乎只返回一个,最后一个。

Events in slice: 10000
Events in slice: 10000
Events in slice: 4501
TOTAL slices in sequence: 1

为什么我的递归调用的结果也没有产生?一个范围的事情?

2 个答案:

答案 0 :(得分:4)

正如约翰已经告诉过你的那样,你也必须得到其他切片:

let rec read stream startFrom (conn : IEventStoreConnection) = 
    seq {
        let size = 10000
        let slice = conn.ReadStreamEventsForwardAsync(stream, startFrom, size, true).Result

        Console.WriteLine("Events in slice: " + slice.Events.Count().ToString())

        if (slice.IsEndOfStream) 
        then
           yield slice
        else
           yield slice // here
           yield! read stream (startFrom + 1 * size) conn 
    }

我认为你可以使用内部函数清理一下这个:

let read (conn : IEventStoreConnection) stream startFrom = 
    let size = 10000
    let rec loop startFrom =
       seq {
           let slice = conn.ReadStreamEventsForwardAsync(stream, startFrom, size, true).Result

           Console.WriteLine("Events in slice: " + slice.Events.Count().ToString())

           if (slice.IsEndOfStream) 
           then
              yield slice
           else
              yield slice // here
              yield! loop (startFrom + 1 * size)
       }
    loop startFrom

答案 1 :(得分:1)

对于另一种观点(它不会尝试以这种方式封装切片加载,选择单独管理该方面以便并行化事件的“播放”,与NES或GES一起使用,请参阅loading/deserialization loop in FunDomain

注意FunDomain中的所有代码实际上只是FsUno.Prod重构了。