我可以拥有一个侦听和响应2个事件的异步代理吗?

时间:2015-11-18 13:43:34

标签: asynchronous f# agent

我想让代理充当SMTP服务器,异步等待电子邮件和服务请求以检索收到的电子邮件列表。代理看起来像:

let agent = Agent.Start(fun inbox ->    
  let rec loop emails = async {
     let! email = ReceiveEmail()
     let emails = email::emails
     let! emailStatusRequest = inbox.Receive()
     match emailStatusRequest with
     | Get channel -> channel.Reply emails
     return! loop emails }
  loop [])

这将等待电子邮件,然后等待状态请求。如何解除订购,以便代理响应首先发生的事件 - 收到电子邮件的事件或收到电子邮件事件的请求? 代理商甚至是建模的合适工具吗?

1 个答案:

答案 0 :(得分:2)

我会将ReceiveEmail部分移到其自己的异步循环中,并让它向您的代理发布消息。

类似这样的事情(警告:未经测试 - 视为伪代码):

type AgentCommands =
   | Received of Email
   | StatusRequest of RequestParams
   | ...

let agent = Agent.Start(fun inbox ->    
  let rec loop emails = async {
     let! cmd = inbox.Receive
     match cmd with
     | Received email ->
        let emails = email::emails
        return! loop emails
     | StatusRequest emailStatusRequest ->
         match emailStatusRequest with
         | Get channel -> channel.Reply emails
     return! loop emails }
  loop [])

let receiveLoop = async {
      while true do
         let! email = ReceiveEmail()
         agent.Post (Received email)   
   } |> Async.Start

当然你可能需要CancellationToken支持......你会得到它;)