创建只有一些消息得到响应的代理?

时间:2013-09-30 19:49:59

标签: f# mailboxprocessor

是否可以创建仅在有时发布回复的邮箱代理?从它的外观来看,在我看来,如果你想发布回复,你必须总是发送一个异步回复频道。

对于我的用例,我真的希望能够灵活地将某些消息只需要传递给代理,而其他消息我想要获得同步或异步回复。

1 个答案:

答案 0 :(得分:8)

我不确定我是否正确理解了这个问题 - 但你当然可以使用歧视联盟作为你的信息类型。然后你可以得到一些包含AsyncReplyChannel<T>的案例(消息类型)和一些不带有它的消息(并且不需要回复)。

例如,对于添加数字的简单代理,您可以Add(不需要响应)和Get需要响应。此外,Get带有一个布尔值,指定我们是否应该将状态重置为零:

type Message = 
  | Add of int
  | Get of bool * AsyncReplyChannel<int>

然后,代理会重复接收消息,如果消息为Get,则会发送回复:

let counter = MailboxProcessor.Start(fun inbox -> 
  let rec loop count = async {
    let! msg = inbox.Receive()
    match msg with 
    | Add n -> return! loop (count + n) // Just update the number
    | Get (reset, repl) ->
        repl.Reply(count)               // Reply to the caller 
        let count = if reset then 0 else count // get new state
        return! loop count }            // .. and continue in the new state
  loop 0 )

然后,您可以使用Post方法发送不需要回复的邮件,PostAndReply发送通过异步回复频道返回内容的邮件:

counter.Post(Add 10)
counter.PostAndReply(fun r -> Get(true, r))
counter.PostAndReply(fun r -> Get(false, r))