【发布时间】:2015-06-29 05:34:21
【问题描述】:
我目前有一个代理通过不断向自己发布“工作”消息来进行大量数据处理。
有时,此代理的客户端希望中断此处理以安全地访问数据。
为此,我认为向代理发布异步消息以便代理在安全状态下可以运行会很好。这工作正常,消息如下所示:
type Message = |Sync of Async<unit>*AsyncReplyChannel<unit>
而代理处理就变成了:
match mailbox.Receive () with
| Sync (async, reply) -> async |> Async.RunSynchronously |> reply.Reply
只要客户端不需要从异步返回一些值,这很有效,因为我已将异步/回复限制为单元类型,并且我不能在可区分联合中使用泛型类型。
解决此问题的最佳尝试涉及到包装器异步和等待句柄,但这看起来很混乱,而且不像我对 F# 所期望的那样优雅。我也是 F# 中异步工作流的新手,所以我很可能在这里错过/误解了一些概念。
所以问题是;如何在代理响应中返回泛型类型?
【问题讨论】:
-
当然你可以在消息中使用泛型:
type Message<'a> = Sync of ...*AsyncReplyChannel<'a>你可能只需要冒泡这一切...... -
顺便说一句:当你只是用
RunSynchronously运行它时,为什么要使用Async<unit>- 在这种情况下,一个简单的() -> ()也可以(或者如果你想要它通用:@ 987654327@ -
另一件事:您使用的是开箱即用的
MailboxProcessor吗?因为.Receive应该是异步的(所以它不应该与match一起使用)——在这种情况下,传递异步工作流是有意义的 -
嗯,我发誓我尝试在联合中使用泛型参数,我猜这解决了它(但是当它刚刚使用时,它与 Message 定义中定义的类型参数看起来有点混乱我有许多案例中的一个)。
-
关于异步 vs ()->(),好吧,不是真的,我仍然在搞乱我的架构,我的想法是,因为这取决于代理应该如何以及何时执行任务运行并且所有客户端都知道“它将在未来某个时间在其他线程上运行”,我认为异步将是一个不错的语义选择。它还使客户端可以轻松切换同步上下文以及更新 ui。
标签: asynchronous f# agent