0

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...

asked Jun 15, 2012 at 0:19

1 Answer 1

2

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
answered Jun 15, 2012 at 1:28
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.