F#异步 - 两个结构之间的差异

时间:2011-08-01 22:28:25

标签: asynchronous f#

写这样的东西之间是否有区别:

MailboxProcessor.Start(fun inbox -> async {
    let rec loop bugs =
        let! msg = inbox.Receive()
        let res = //something
        loop res
    loop []})

并且这样写:

MailboxProcessor.Start(fun inbox ->
    let rec loop bugs = async {
        let! msg = inbox.Receive()
        let res = //something
        do! loop res }
    loop [])

谢谢!

1 个答案:

答案 0 :(得分:7)

第一个示例不是有效的F#代码,因为let!只能在计算表达式中立即使用。在您的示例中,您在普通函数中使用它 - 它的主体不是计算表达式,因此在该位置不允许let!

要使其有效,您需要将loop函数的正文包裹在async中:

MailboxProcessor.Start(fun inbox -> async {
    let rec loop bugs = async {
        let! msg = inbox.Receive()
        let res = //something
        return! loop res }
    return! loop []})

您也可以将外部async { .. }块保留在代码段中 - 然后您只需使用return!来调用loop函数,而不是仅仅返回它(但除此之外)现在没有显着差异。)

请注意,我使用的是return!而不是do! - 这实际上有所不同,因为return!表示尾调用,这意味着可以丢弃当前正文的其余部分。如果使用do!,那么async会在堆中分配类似堆栈帧的内容,因此在递归循环函数中使用do!会泄漏内存。