我一直在試圖學習如何使用基於異步消息的方法。以下是我正在嘗試做的簡化版本。我試圖在一個對象內的一個MailboxProcessor
內使用一個有限狀態機。總的來說,與使用基於事件的方法相比,邏輯似乎更直接。當我嘗試使用Async.Parallel
時,我遇到了一個問題。在printfn "Eval %i" v
聲明之後的代碼中,對於每個i1
& i2
而不是僅一次評估兩次。這導致我相信我沒有正確使用Async.Parallel
。是否有異步工作流應該使用的另一種方法?如何在異步工作流中使用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
您不需要'async {}'塊。 '[i1; i2] |> Seq.map(fun n - > n.Eval)|> Async.Parallel |> Async.RunSynchronously'將起作用。 – Daniel
感謝您的評論,但實際的實施不會同步運行。我的問題是如何在異步工作流中並行評估異步返回數組(在這種情況下是'Eval'方法)。有關更大的示例,請參見[link](https://gist.github.com/mndrake/8440854#file-utopia-fsx-L121)。 – mndrake
也許只是將'Async.Parallel'的結果傳遞給'Async.Ignore |> Async.Start'?一旦他們完成,你想用'Eval'的結果做什麼? – Tarmil