首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MailboxProcessor.PostAndReply设计选择

MailboxProcessor.PostAndReply设计选择
EN

Stack Overflow用户
提问于 2012-02-29 22:57:39
回答 1查看 1.4K关注 0票数 12

查看:

代码语言:javascript
复制
member this.PostAndReply : (AsyncReplyChannel<'Reply> -> 'Msg) * ?int -> 'Reply

我不明白为什么签名对我来说这么违反直觉。我们要做的是向代理发送一条消息,并等待回复。为什么我们要给他一个奇怪的功能作为“消息”?

再次查看此MSDN代码片段:

代码语言:javascript
复制
let rec loop() =
    printf "> "
    let input = Console.ReadLine()
    printThreadId("Console loop")
    let reply = agent.PostAndReply(fun replyChannel -> input, replyChannel)
    if (reply <> "Stopping.") then
        printfn "Reply: %s" reply
       loop()
    else
        ()
loop()

我更喜欢这样的东西:

代码语言:javascript
复制
member this.PostAndReply : 'Msg * ?int -> 'Reply

谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-02-29 23:10:56

当您第一次看到这个类型签名时,它看起来非常令人困惑,但它确实有意义。

F#库设计

背后的想法是,当您调用PostAndReply时,您需要为它提供一个函数,该函数:

  • 在F#运行时构建用于将消息发送回调用者的通道(通道表示为AsyncReplyChannel<'Reply>类型的值)之后,构造一个F#类型的消息(将发送给代理)

您构造的消息需要包含回复通道,但是F#库不知道您希望如何表示消息(因此它也不知道您希望如何在消息中存储回复通道)。因此,库要求您编写一个函数,该函数将在系统构造通道后为代理构造消息。

Your alternative suggestion

您建议的问题是,如果PostAndReply的类型为'Msg -> 'Reply,则代理在调用Receive后收到的消息将是以下类型:

代码语言:javascript
复制
'Msg * AsyncReplyChannel<'Reply>

..。因此,接收到代理的每条消息也必须携带一个用于发送回复的通道。但是,您可能不希望对收到的每条消息都发送回复,因此这并不能真正起作用。也许你可以使用类似这样的东西:

代码语言:javascript
复制
'Msg * option<AsyncReplyChannel<'Reply>>

..。但这只会变得越来越复杂(而且它仍然不太正确,因为您只能回复来自'Msg的一些消息,而不是所有消息)。

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9501380

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档