Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将MailboxProcessor封装到F#中并在F#中可观察到的好方法是什么?_F#_System.reactive_Actor - Fatal编程技术网

将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
本身不提供muchA
MailboxProcessor
>是一个非常低级别的构造,可用于实现数据流/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))