这是一个有趣的问题,并且存在很多可能的观点。我认为,最显着的方面是,选择会影响你如何在这两个组件之间的接口设计的API:
在“消费”的办法,生产者有一个非常简单的API,其中它会触发一些事件每当产生一个价值,你的消费者就会订阅它。这意味着您可以让其他订阅者倾听来自制作人的更新,并从这个问题中做出比您的消费者更多的东西。
在“调用最新”方法中,生产者可能需要写入,以保持当前状态并丢弃旧值。然后它将提供阻塞异步API以获取最新值。尽管如此,它仍然可以为其他消费者揭露事件。消费者将需要积极调查变化(在某种忙碌的环境中)。
您也可以在“Consume all”中拥有一个带有事件的生产者,但随后创建另一个组件来侦听任何给定的事件,保留最新值并通过阻止异步调用将其提供给任何其他客户端。
这里一些优点/缺点我能想到的:
- 在(1)的生产是非常简单;消费者很难写
- (2)生产者需要做更多的工作,但消费者很简单
- 在(3)中,您要添加另一个层,但是要以相当可重用的方式。
我可能会去与(2)(如果我只需要这一个数据源)或与(3)检查后,它不会影响性能。
至于(3)中,我在想什么会是这个样子的素描:
type KeepLastMessage<'T> =
| Update of 'T
| Get of AsyncReplyChannel<'T>
type KeepLast<'T>(initial:'T, event:IObservable<'T>) =
let agent = MailboxProcessor.Start(fun inbox ->
let rec loop last = async {
let! msg = inbox.Receive()
match msg with
| Update last -> return! loop last
| Get ch -> ch.Reply(last); return! loop last }
loop initial)
member x.AsyncGet() = agent.PostAndAsyncReply(Get)
非常感谢您Petricek博士,这和F#comunity所有其他工作 –