我想处理消息类型
Add x
让程序记住数字x
Print
让它打印所有记住的数字
我为什么要这样写:
open System
type Message =
| Add of int
| Print
let mailbox = new MailboxProcessor<Message>(fun inbox ->
let rec loop history = async{
let! msg=inbox.Receive()
match msg with
| Add x -> return! loop(history + x.ToString()+" ")
| Print ->
printfn "%s" history
return! loop(history)
}
loop ""
)
[<EntryPoint>]
let main argv =
mailbox.Start()
mailbox.Post(Add 12)
mailbox.Post(Add 56)
mailbox.Post(Print)
mailbox.Post(Add 34)
mailbox.Post(Print)
ignore <| Console.ReadLine()
0
而不是:
open System
open System.Reactive.Subjects
type Message =
| Add of int
| Print
let subject = new Subject<Message>()
[<EntryPoint>]
let main argv =
subject
|> Observable.scan(fun history msg ->
match msg with
| Add x -> history + x.ToString()+" "
| Print ->
printfn "%s" history
history
) ""
|> Observable.subscribe(fun _->())
|> ignore
subject.OnNext(Add 12)
subject.OnNext(Add 56)
subject.OnNext(Print)
subject.OnNext(Add 34)
subject.OnNext(Print)
ignore <| Console.ReadLine()
0
MailboxProcessor
增加了额外的复杂程度。我需要一个状态机,它接受一个状态并返回一个状态。但它迫使我采取inbox
,用于接收国家。
IObservable
有什么好处吗?
答案 0 :(得分:3)
不,他们不是彼此重复的。 MailboxProcessor
和IObservable
是两种不同计算模型的低级构建块 - 演员模型和功能反应式编程。
两者都处理异步性,但强调different qualities。根据您在简单示例中注意到的情况,可能可以根据其中一个构建您的解决方案 - 但您会发现在特定上下文中使用的一个或另一个更自然。
MailboxProcessors
对于资源(例如文件)的线程安全,无锁访问特别有用。您可以让多个线程通过异步接口操作资源,MailboxProcessor
保证一次只处理其中一个请求。