我在包含字段Id
,Last
和TimeStamp
的SQL数据库中记录了实时股票报价。最后是当前股票价格(作为双倍),TimeStamp
是记录价格变化时的DateTime
。
我想以与它进来相同的方式重播此流,这意味着如果价格变化最初相隔12秒,则价格变化事件触发(或类似的事情)应相隔12秒。
在C#中,我可能会创建一个集合,按DateTime
对其进行排序,然后使用时间差来触发事件,以了解何时触发下一次价格变动。我意识到F#有很多与事件有关的很酷的新东西,但我不知道我怎么会在F#中开始这个。关于我如何处理此问题的任何想法/代码片段/有用链接?
答案 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()