如何在异步工作流中使用Async.Parallel?

时间:2014-01-15 16:48:38

标签: asynchronous f# mailboxprocessor

我一直在努力学习如何使用基于异步消息的方法。下面是我试图做的简化版本。我正在尝试在对象内的MailboxProcessor内使用有限状态机。总的来说,与使用基于事件的方法相比,逻辑似乎更简单。我尝试使用Async.Parallel时遇到了问题。在printfn "Eval %i" v语句之后的代码中,对i1& i2而不是每次只有一次。这让我相信我没有正确使用Async.Parallel。是否有一种替代方法应该在异步工作流程中使用?

type Input(v) = 

    let agent = 
        MailboxProcessor.Start(fun inbox -> 
            let rec loop() = 
                async { 
                    let! (msg : AsyncReplyChannel<int>) = inbox.Receive()
                    printfn "Eval %i" v
                    msg.Reply(v)
                    return! loop()
                }
            loop())

    member this.Eval = agent.PostAndAsyncReply(fun r -> r)

let i1 = Input(1)
let i2 = Input(2)

async { 
    let! nodeValues = [ i1; i2 ]
                      |> Seq.map(fun n -> n.Eval)
                      |> Async.Parallel
    return nodeValues
}
|> Async.RunSynchronously

1 个答案:

答案 0 :(得分:3)

这是F#3.0中的错误。 Async.Parallel两次致电Seq.toArray。在F#3.1下运行您的代码,它只会打印一次。 Here's the fix in the F# source repository.