重播F#中录制的数据流

时间:2011-03-20 23:37:08

标签: sql database events f#

我在包含字段IdLastTimeStamp的SQL数据库中记录了实时股票报价。最后是当前股票价格(作为双倍),TimeStamp是记录价格变化时的DateTime

我想以与它进来相同的方式重播此流,这意味着如果价格变化最初相隔12秒,则价格变化事件触发(或类似的事情)应相隔12秒。

在C#中,我可能会创建一个集合,按DateTime对其进行排序,然后使用时间差来触发事件,以了解何时触发下一次价格变动。我意识到F#有很多与事件有关的很酷的新东西,但我不知道我怎么会在F#中开始这个。关于我如何处理此问题的任何想法/代码片段/有用链接?

1 个答案:

答案 0 :(得分:11)

我认为你会喜欢F#解决方案:-)。

为了使示例简单,我将价格和时间戳存储在包含元组的列表中(第一个元素是上次更新的延迟,第二个元素是价格)。将输入数据转换为此格式应该不会太困难。例如:

let prices = [ (0, 10.0); (1000, 10.5); (500, 9.5); (2500, 8.5) ]

现在我们可以创建一个用于重放流程的新事件。在创建它之后,我们立即附加一些将打印价格更新的处理程序:

let evt = new Event<float>()
evt.Publish.Add(printfn "Price updated: %f")

最后一步是实现重放 - 这可以使用循环遍历值的异步工作流完成,异步等待指定的时间然后触发事件:

async { for delay, price in prices do
          do! Async.Sleep(delay)
          evt.Trigger(price) }
|> Async.StartImmediate

我正在使用StartImmediate启动工作流,这意味着它将在当前线程上运行(等待是异步的,因此它不会阻塞线程)。保持所有单线程使其更简单(例如,您可以安全地访问GUI控件)。

编辑要将功能包装在可以从应用程序的其他部分使用的某个组件中,您可以定义如下类型:

type ReplyDataStream(prices) =
  let evt = new Event<float>()
  member x.Reply() = 
    // Start the asynchronous workflow here
  member x.PriceChanged = 
    evt.Publish

然后,用户可以创建该类型的实例,使用stream.PriceChanged.Add(...)附加其事件处理程序,然后使用Reply()

开始重播记录的更改