我有以下使用FSharp.Reactive的F#代码。函数reactToEvents接受两个事件源并生成一个应用程序状态源。然后UI使用应用程序状态
open FSharp.Reactive
let reactToEvents (initialSettings:Settings)
(incomingTweets: ITweet IObservable)
(uiActions: UserInput IObservable) : State IObservable =
let initialState = { settings = initialSettings; tweets = [] }
let tweetInput = Observable.map TweetReceived incomingTweets
let userInput = Observable.map UserAction uiActions
let allInput = Observable.merge userInput tweetInput
Observable.scan transition initialState allInput
在上面的函数中,在UI线程上生成uiActions时,会在一个线程上生成incomingTweets事件。
使用Observable.merge合并两个源是否安全,就像我上面那样?
使用上面的Observable.scan扫描生成的源是否安全?
如果这不正确,那么正确的方法是什么?
谢谢!
更新1:
我希望至少Observable.merge不关心线程。 我发现了这个,似乎说这样使用它们是不安全的:
http://msdn.microsoft.com/en-us/library/ee353488.aspx
http://msdn.microsoft.com/en-us/library/ee353749.aspx
“对于每个观察者,注册的中间观察对象不是线程安全的。也就是说,源不会在不同的线程上同时触发源的观察。”
那么正确的方法是什么?
更新2:
这是一个混乱。我链接的文档是用于从名称空间Microsoft.FSharp.Control.Observable合并和扫描的函数。这与我在我的代码中使用的Rx不同。对于真正的Rx,您需要使用库FSharp.Reactive和FSharp.Reactive.Observable下的函数
答案 0 :(得分:5)
使用Observable.merge合并两个源是否安全,就像我上面那样? 使用上面的Observable.scan扫描生成的源是否安全?
是的,Rx保证这是安全的。但是,要意识到结果将在不同的线程上出现。如果您希望随后使用结果更新UI元素,则需要通过ObserveOn
(或等效的F#)将结果封送到UI线程