Waitgroups in F#
Our example demonstrates how to wait for multiple asynchronous operations to finish using F#’s Async workflow and Task parallel library.
open System
open System.Threading.Tasks
// This is the function we'll run in every task.
let worker (id: int) = async {
printfn "Worker %d starting" id
// Sleep to simulate an expensive task.
do! Async.Sleep 1000
printfn "Worker %d done" id
}
[<EntryPoint>]
let main argv =
// Create a list of worker tasks
let tasks =
[1..5]
|> List.map (fun i -> worker i |> Async.StartAsTask)
// Wait for all tasks to complete
Task.WhenAll(tasks) |> Async.AwaitTask |> Async.RunSynchronously
// Note that this approach has no straightforward way
// to propagate errors from workers. For more
// advanced use cases, consider using F#'s `Async.Catch`
// or other error handling mechanisms.
0 // return an integer exit codeTo run the program:
$ dotnet fsi waitgroups.fsx
Worker 1 starting
Worker 2 starting
Worker 3 starting
Worker 4 starting
Worker 5 starting
Worker 1 done
Worker 2 done
Worker 3 done
Worker 4 done
Worker 5 doneThe order of workers starting up and finishing is likely to be different for each invocation.
In this F# version:
We define a
workerfunction that takes anidand returns anAsync<unit>. This is similar to the original Go function but uses F#’sasynccomputation expression.In the
mainfunction, we create a list of tasks usingList.mapandAsync.StartAsTask. This is analogous to launching several goroutines in the Go version.We use
Task.WhenAllto wait for all tasks to complete, which is similar to theWaitGroup.Wait()in the Go version.We run the entire async workflow synchronously using
Async.RunSynchronously.Error handling in this simple example is not explicitly addressed, but F# provides mechanisms like
Async.Catchfor more advanced error handling in asynchronous code.
This F# implementation achieves the same goal as the original Go code, demonstrating how to run multiple asynchronous operations concurrently and wait for their completion.