Parallelism and Channels

Reactive programming: FSharp.Control.Reactive (Rx), FSharp.Control.AsyncSeq / TaskSeq (async sequences: taskSeq { }), IAsyncEnumerable interop.

// Data parallelism
let squares = Array.Parallel.map (fun x -> x * x) [| 1 .. 1_000_000 |]
let total = [| 1 .. 1_000_000 |] |> Array.Parallel.sumBy int64      // F# 8+ adds more Array.Parallel functions
System.Threading.Tasks.Parallel.For(0, 10, fun i -> printfn "%d" i) |> ignore
let plinq = [| 1 .. 100 |].AsParallel().Select(fun x -> x * 2).ToArray()   // PLINQ (open System.Linq)

// Channels: async producer/consumer queues (System.Threading.Channels)
open System.Threading.Channels
open System.Threading.Tasks
let channel = Channel.CreateBounded<int>(10)
let producer = task {
    for i in 1 .. 5 do do! channel.Writer.WriteAsync i
    channel.Writer.Complete()
}
let consumer = task {
    let mutable sum = 0
    let reader = channel.Reader
    let mutable more = true
    while more do
        let! available = reader.WaitToReadAsync()
        if available then
            match reader.TryRead() with
            | true, v -> sum <- sum + v
            | _ -> ()
        else more <- false
    return sum
}
Task.WaitAll(producer, consumer)
consumer.Result                                    // 15

// Thread safety primitives
let lockObj = obj ()
let mutable shared = 0
lock lockObj (fun () 
…