I've been trying to learn how to use asynchronous message based methods. Below is a simplified version of what I was trying to do. I'm trying to use a finite state machine within a MailboxProcessor
within an object. Overall it appears that the logic can be much more straightforward compared to using event based methods. I have an issue though when I try to use Async.Parallel
. In the code following the printfn "Eval %i" v
statement is getting evaluated twice for i1
& i2
instead of just one time for each. Which leads me to believe that I am not properly using Async.Parallel
. Is there an alternative method that should be used within an asynchronous workflow?
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
This is a bug in F# 3.0. Async.Parallel
calls Seq.toArray
twice. Run your code under F# 3.1 and it will only print once. Here's the fix in the F# source repository.