我可以有一个异步代理来监听和响应 2 个事件吗?

Can I have an asynchronous agent that listens and responds to 2 events?

我想要一个充当 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 [])

这将等待电子邮件,然后等待状态请求。我将如何解耦排序,以便代理响应先发生的事件 - 电子邮件接收事件或获取电子邮件事件的请求? 代理甚至是对此建模的正确工具吗?

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

类似这样的东西(警告:未测试 - 视为伪代码):

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 支持......你会得到它 ;)