来自 agent/mailboxprocessor 的一般回复?
Generic reply from agent/mailboxprocessor?
我目前有一个代理,它通过不断向自己发送 "work" 消息来处理大量数据。
有时此代理的客户端想要中断此处理以安全地访问数据。
为此,我认为只要代理处于安全状态,就可以向代理发送异步消息 运行 会很好。这工作正常,消息如下所示:
type Message = |Sync of Async<unit>*AsyncReplyChannel<unit>
代理处理简单地变成:
match mailbox.Receive () with
| Sync (async, reply) -> async |> Async.RunSynchronously |> reply.Reply
只要客户端不需要 return 来自异步的一些值,这就很好用,因为我已经将 async/reply 限制为类型 unit 并且我不能使用通用类型在受歧视的联盟中。
我解决这个问题的最佳尝试涉及包装器异步和等待处理,但这看起来很混乱,而且不像我对 F# 的期望那样优雅。我也是 F# 异步工作流的新手,所以我很可能已经 missed/misunderstood 了解了一些概念。
所以问题是;我如何 return 代理响应中的通用类型?
使这变得困难的是,在您当前的版本中,代理必须以某种方式计算值,然后将其传递给通道,而不知道值的类型是什么。在 F# 中以静态类型的方式执行此操作很棘手。
如果您将消息设置为通用消息,那么它将起作用,但代理将只能处理一种类型的消息(Message<T>
中的 T
类型)。
另一种方法是简单地将 Async<unit>
传递给代理,让调用者为每个特定类型传递值。所以,你可以这样写消息和代理:
type Message = | Sync of Async<unit>
let agent = MailboxProcessor.Start(fun inbox -> async {
while true do
let! msg = inbox.Receive ()
match msg with
| Sync (work) -> do! work })
当您使用 PostAndReply
时,您可以访问回复通道 - 而不是将通道传递给代理,您可以只在本地 async
块中使用它:
let num = agent.PostAndReply(fun chan -> Sync(async {
let ret = 42
chan.Reply(ret) }))
let str = agent.PostAndReply(fun chan -> Sync(async {
let ret = "hi"
chan.Reply(ret) }))
我目前有一个代理,它通过不断向自己发送 "work" 消息来处理大量数据。
有时此代理的客户端想要中断此处理以安全地访问数据。
为此,我认为只要代理处于安全状态,就可以向代理发送异步消息 运行 会很好。这工作正常,消息如下所示:
type Message = |Sync of Async<unit>*AsyncReplyChannel<unit>
代理处理简单地变成:
match mailbox.Receive () with
| Sync (async, reply) -> async |> Async.RunSynchronously |> reply.Reply
只要客户端不需要 return 来自异步的一些值,这就很好用,因为我已经将 async/reply 限制为类型 unit 并且我不能使用通用类型在受歧视的联盟中。
我解决这个问题的最佳尝试涉及包装器异步和等待处理,但这看起来很混乱,而且不像我对 F# 的期望那样优雅。我也是 F# 异步工作流的新手,所以我很可能已经 missed/misunderstood 了解了一些概念。
所以问题是;我如何 return 代理响应中的通用类型?
使这变得困难的是,在您当前的版本中,代理必须以某种方式计算值,然后将其传递给通道,而不知道值的类型是什么。在 F# 中以静态类型的方式执行此操作很棘手。
如果您将消息设置为通用消息,那么它将起作用,但代理将只能处理一种类型的消息(Message<T>
中的 T
类型)。
另一种方法是简单地将 Async<unit>
传递给代理,让调用者为每个特定类型传递值。所以,你可以这样写消息和代理:
type Message = | Sync of Async<unit>
let agent = MailboxProcessor.Start(fun inbox -> async {
while true do
let! msg = inbox.Receive ()
match msg with
| Sync (work) -> do! work })
当您使用 PostAndReply
时,您可以访问回复通道 - 而不是将通道传递给代理,您可以只在本地 async
块中使用它:
let num = agent.PostAndReply(fun chan -> Sync(async {
let ret = 42
chan.Reply(ret) }))
let str = agent.PostAndReply(fun chan -> Sync(async {
let ret = "hi"
chan.Reply(ret) }))