Skip to content

Instantly share code, notes, and snippets.

@baronfel
Last active February 27, 2023 21:32
Show Gist options
  • Save baronfel/444d3f8d5aab8179eb2f279571afc4ad to your computer and use it in GitHub Desktop.
Save baronfel/444d3f8d5aab8179eb2f279571afc4ad to your computer and use it in GitHub Desktop.
concurrency/parallelism using Asyncs
#r "nuget: Nito.AsyncEx, 5.1.2"
open System.Threading
open System.Threading.Tasks
open Nito.AsyncEx
let work x y =
async {
do! Async.Sleep 1
return 1 + 2
}
let printlock = obj()
let inline log tag msg =
lock printlock (fun _ ->
printfn $"[%s{tag}]\t%s{msg}"
)
let sendWorkers ctx x y =
async {
let workId = string (x,y)
do! Async.SwitchToContext ctx
log workId $"Starting work on thread {Thread.CurrentThread.ManagedThreadId}"
let! workerBee1 = work (x) (y) |> Async.StartChild
log workId $"Starting subitem 2 on {Thread.CurrentThread.ManagedThreadId}"
let! workerBee2 = work (x) (y + 1) |> Async.StartChild
log workId $"Starting subitem 3 on {Thread.CurrentThread.ManagedThreadId}"
let! workerBee3 = work (x) (y + 2) |> Async.StartChild
// collect results
log workId $"waiting for results on {Thread.CurrentThread.ManagedThreadId}"
let! result1 = workerBee1
let! result2 = workerBee2
let! result3 = workerBee3
//print results
log workId $"done on {Thread.CurrentThread.ManagedThreadId}"
}
let ROWS = 10
// use this block to show off concurrency
let asyncCtx = new AsyncContext()
AsyncContext.Run<unit[]>(System.Func<Task<unit[]>>(fun () ->
let ctx = SynchronizationContext.Current
Seq.init ROWS (fun i -> sendWorkers ctx i 0)
|> Async.Parallel
|> Async.StartAsTask
))
asyncCtx.Execute()
// use this block to show off parallelism
// Seq.init ROWS (fun i -> sendWorkers null i 0)
// |> Async.Parallel
// |> Async.RunSynchronously
// System.Console.ReadLine() |> ignore
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment