将MailboxProcessor封装到F#中并在F#中可观察到的好方法是什么?
假设我有一个将MailboxProcessor封装到F#中并在F#中可观察到的好方法是什么?,f#,system.reactive,actor,F#,System.reactive,Actor,假设我有一个MailboxProcessor,它接收AsyncReplyChannel消息并异步执行它们 有没有一种简单的方法可以像这样从MailboxProcessor构建一个IObservable let actor=MailboxProcessor.Start(有趣的收件箱-> 异步的{ 设可变x=0 尽管如此 let!ch:AsyncReplyChannel=inbox.Receive() ch.答复十 x ch)//也会触发obs 我认为在热/冷观测等方面需要做出一些决定 这里涉及到
MailboxProcessor
,它接收AsyncReplyChannel
消息并异步执行它们
有没有一种简单的方法可以像这样从MailboxProcessor
构建一个IObservable
let actor=MailboxProcessor.Start(有趣的收件箱->
异步的{
设可变x=0
尽管如此
let!ch:AsyncReplyChannel=inbox.Receive()
ch.答复十
x ch)//也会触发obs
我认为在热/冷观测等方面需要做出一些决定
这里涉及到这一点:如果您想获得一个现有的
邮箱处理器
并获得一个IObservable
,它将在邮箱处理器响应消息时被触发,那么我认为没有办法做到这一点-没有钩子可以让您检测到这一点
这样做的方法是在MailboxProcessor
上定义某种包装器。例如,您可以定义NotifyingMailboxProcessor
,在每次处理'Msg
类型的消息时触发'Evt
类型的事件。您可以从以下内容开始:
type NotifyingMailboxProcessor<'Msg, 'Evt>(mbox:MailboxProcessor<'T>) =
let evt = Event<'E>()
member x.OnPostAndReply = evt.Publish
member x.PostAndReply<'R>(f:AsyncReplyChannel<'R> -> 'T, g:'T -> 'R -> 'E) =
let mutable msg = Unchecked.defaultof<_>
let res = mbox.PostAndReply(fun ch -> msg <- f(ch); msg)
evt.Trigger(g msg res)
res
type NotifyingMailboxProcessor =
static member Start<'Msg, 'Evt>(f) =
NotifyingMailboxProcessor<'Msg, 'Evt>(MailboxProcessor.Start(f))
为什么要这样做?邮箱处理器和Observable代表两种不同的计算范式。MailboxProcessor不复制IObservable。如果你想使用反应式编程,你可以使用反应式扩展,让处理器发布到一个主题。
IObservable
本身不提供muchAMailboxProcessor
>是一个非常低级别的构造,可用于实现数据流/CSP管道或代理。但它的级别太低了一点,因此使用例如TPL数据流块来实现CSP管道或Akka.NET等来实现代理要容易得多。MailboxProcessor不提供代理框架提供的任何功能,除了缓冲区put和worker线程。此时,您甚至可以询问您是否需要MailboxProcessor,或者通道和iSyncEnumerable
是否可以完成相同的工作-他们可以。事实上,他们可以提供更好的服务isolation@PanagiotisKanavos问题是我想向流程发送有序的输入(MailboxProcessor
适用于此),但进程的输出可以以不受控制的间隔返回(IObservable
)
let actor = NotifyingMailboxProcessor.Start<AsyncReplyChannel<int>, int>(fun inbox ->
async {
let mutable x = 0
while true do
let! (ch : AsyncReplyChannel<int>) = inbox.Receive ()
ch.Reply x
x <- x + 1
})
actor.OnPostAndReply.Add(printfn "Message: %A")
actor.PostAndReply((fun ch -> ch), (fun msg ans -> ans))