<Query Kind="FSharpProgram" />

// ------------------------------
open System.Threading
// ------------------------------

let tid () = Thread.CurrentThread.ManagedThreadId
let trace s = printfn "    [%d] %s" (tid()) s

// ------------------------------

printfn "\r\n... [%d] RunSynchronously" (tid())

let async0 = async { trace("async0"); return 10+10 }  // Async<int>
let resa0 = Async.RunSynchronously async0              // wait result
printfn "... [%d] resa0: %d" (tid()) resa0

// ------------------------------

printfn "\r\n... [%d] StartWithContinuations" (tid())
Async.StartWithContinuations 
    (async0, 
    (fun n -> printfn "... [%d] success: %d" (tid()) n), 
    (fun x -> printfn "... [%d] exception: %s" (tid()) x.Message), 
    (fun _ -> printfn "... [%d] cancelled" (tid()) ))

// ------------------------------

printfn "\r\n... [%d] StartAsTask" (tid())
let task0 = Async.StartAsTask async0
printfn "... [%d] Do some other work..." (tid())
let rest0 = task0.Result // task0.Wait()
printfn "... [%d] rest0: %d" (tid()) rest0
                                                          
// ------------------------------

printfn "\r\n... [%d] Parallel" (tid())

let async1 = async { trace("async1"); return 10+10 }     // Async<int>
let async2 = async { trace("async2"); return 20+20 }     // Async<int>
let res12 = Async.RunSynchronously 
                (Async.Parallel [ async1; async2 ])      // Async<int[]>
printfn "... [%d] res12: %A" (tid()) res12             // [|20; 40|]

// ---

let res12' = 
    [ async1; async2 ]
    |> Async.Parallel                                   // Async<int []>
    |> Async.RunSynchronously                           // int[]

printfn "... [%d] res12': %A" (tid()) res12'                // [|20; 40|]

// ------------------------------