這是一個有趣的問題,並且存在很多可能的觀點。我認爲,最顯着的方面是,選擇會影響你如何在這兩個組件之間的接口設計的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所有其他工作 –