I'm a bit newbie with the async workflow and I think it has somethings I am not understand so well...I'm following the book Real world functional programming and in it writes the async primitive in this way
let Sleep(time) =
Async.FromContinuations(fun (cont, econt, ccont) ->
let tmr = new System.Timers.Timer(time, AutoReset = false)
tmr.Elapsed.Add(fun _ -> cont())
tmr.Start()
);;
I've tried write my own async primitive using a very slow factorial implementation, the code is it:
let rec factorial(n : int) (mem : bigint) =
match n with
| 0 | 1 -> printfn "%A" mem
| _ -> factorial (n - 1) (mem * bigint(n))
let BigFactorial(numero,mesaje)=
Async.FromContinuations(fun (cont,error,cancelation) ->
printfn "begin number: %s" mesaje
factorial numero 1I |>ignore
printfn "End number: %s ." mesaje
cont())
now I wrote this
Async.RunSynchronously(async{
printfn "Start!!..."
do! BigFactorial(30000,"30M")
do! BigFactorial(10000, "10M")
printfn "End!!..."
})
but it isn't running in async way precisely....
Start!!...
begin number: 30M
2759537246219...(A nice long number!)
end number: 30M .
begin number: 10M .
2846259680917054518906...(other nice number)
End!!...
if I execute it in parallel then works good...
let task1 = async{
printfn "begin"
do! BigFactorial(30000,"30")
printfn "end..."
}
let task2 = async{
printfn "begin"
do! BigFactorial(10000,"10")
printfn "end!!..."
}
Async.RunSynchronously(Async.Parallel[task1;task2])
begin
begin: 30
begin
begin: 10M
//long numbers here
end....
end.....
but I wish know the reason (or the several reasons!) why the first code doesn't work... thanks so much I appreciate any help...
1 Answer 1
As with all async bindings, do! runs on the current thread, and thus your two sequential do!s run sequentially.
If you want them to run in parallel, you must say so explicitly:
async {
printfn "Start!!..."
let! tokenA = BigFactorial (30000, "30M") |> Async.StartChild // on new thread
let! tokenB = BigFactorial (10000, "10M") |> Async.StartChild // on new thread
do! tokenA // block until `BigFactorial (30000, "30M")` finishes
do! tokenB // block until `BigFactorial (10000, "10M")` finishes
printfn "End!!..." }
|> Async.RunSynchronously