module Async = open System.Threading let inline ParallelWithThrottle (millisecondsTimeout:int) (limit:int) (items:'a seq) (operation:'a->Async<'b>) = let semaphore = new System.Threading.SemaphoreSlim(limit, limit) let mutable count = (items |> Seq.length) items |> Seq.map(fun item -> async { let! isHandleAquired = Async.AwaitTask <| semaphore.WaitAsync(millisecondsTimeout=millisecondsTimeout) if isHandleAquired then try return! operation item finally if Interlocked.Decrement(&count) = 0 then semaphore.Dispose() else semaphore.Release() |> ignore else return! failwith "Failled to aquire handle" }) |> Async.Parallel // Example let rec fib n = match n with | 1 | 2 -> 1 | n -> fib(n - 2) + (fib - 1) let op n = async{ let fibN = fib n return (n, fibN) } Async.ParallelWithThrottle 10000 4 [30..45] op |> Async.RunSynchronously |> Seq.iter(fun (n,fibN) -> printfn "The fib number of %d is %d" n fibN)