我可以有一个异步代理来监听和响应 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
支持......你会得到它 ;)
我想要一个充当 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
支持......你会得到它 ;)