Async Workflows
Async is cold (nothing runs until started) and carries a cancellation token implicitly. Task is hot (starts immediately).
let fetchData (id: int) = async {
do! Async.Sleep 500 // non-blocking delay
return $"data for {id}"
}
// Run one
fetchData 1 |> Async.RunSynchronously // blocks; use only at the top level/scripts
// Run many in parallel
let all =
[1 .. 5]
|> List.map fetchData
|> Async.Parallel // Async<string[]>
|> Async.RunSynchronously
// Limit the degree of parallelism
let throttled = Async.Parallel([ for i in 1 .. 20 -> fetchData i ], maxDegreeOfParallelism = 4)
// Sequential
let seqResults = [1 .. 3] |> List.map fetchData |> Async.Sequential
// Fire-and-forget and background start
Async.Start (async { printfn "background" })
let child = async {
let! started = Async.StartChild(fetchData 9, millisecondsTimeout = 2000) // with a timeout
return! started
}
// Cancellation (Async is cancellable by design)
let cts = new System.Threading.CancellationTokenSource()
let longRunning = async {
for i in 1 .. 100 do
do! Async.Sleep 100
printfn "step %d" i
}
Async.Start(longRunning, cts.Token)
cts.CancelAfter 350
// Error handling
let safe = async {
try
let! r = async { return failwit
…