@@ -997,6 +997,15 @@ module Task =
997997
998998 /// Sequence actions, discarding the value of the second argument.
999999 let inline ( <*) a b = lift2 ( fun z _ -> z) a b
1000+
1001+ let foldM f s =
1002+ Seq.fold ( fun acc t -> acc >>= ( flip f) t) ( returnM s)
1003+
1004+ let inline sequence ( s : Task < 'a > list ) =
1005+ let inline cons a b = lift2 List.cons a b
1006+ List.foldBack cons s ( returnM [])
1007+
1008+ let inline mapM f x = sequence ( List.map f x)
10001009
10011010 type TaskBuilder (? continuationOptions , ? scheduler , ? cancellationToken ) =
10021011 let contOptions = defaultArg continuationOptions TaskContinuationOptions.None
@@ -1043,6 +1052,8 @@ module Task =
10431052
10441053 member this.Run ( f : unit -> Task < 'T >) = f()
10451054
1055+ let task = TaskBuilder()
1056+
10461057 type TaskBuilderWithToken (? continuationOptions , ? scheduler ) =
10471058 let contOptions = defaultArg continuationOptions TaskContinuationOptions.None
10481059 let scheduler = defaultArg scheduler TaskScheduler.Default
@@ -1085,3 +1096,47 @@ module Task =
10851096
10861097 member this.Delay f = this.Bind( this.Return (), f)
10871098
1099+ /// Converts a Task into Task<unit >
1100+ let ToTaskUnit ( t : Task ) =
1101+ let continuation _ = ()
1102+ t.ContinueWith continuation
1103+
1104+ /// Creates a task that runs the given task and ignores its result.
1105+ let inline Ignore t = bind ( fun _ -> returnM ()) t
1106+
1107+ /// Creates a task that executes a specified task.
1108+ /// If this task completes successfully, then this function returns Choice1Of2 with the returned value.
1109+ /// If this task raises an exception before it completes then return Choice2Of2 with the raised exception.
1110+ let Catch ( t : Task < 'a >) =
1111+ task {
1112+ try let! r = t
1113+ return Choice1Of2 r
1114+ with e ->
1115+ return Choice2Of2 e
1116+ }
1117+
1118+ #if ! NET40
1119+ /// Creates a task that executes all the given tasks.
1120+ let Parallel ( tasks : seq < unit -> Task < 'a >>) =
1121+ tasks
1122+ |> Seq.map ( fun t -> t())
1123+ |> Array.ofSeq
1124+ |> Task.WhenAll
1125+
1126+ /// Creates a task that executes all the given tasks.
1127+ /// The paralelism is throttled, so that at most ` throttle ` tasks run at one time.
1128+ let ParallelWithTrottle throttle ( tasks : seq < unit -> Task < 'a >>) : ( Task < 'a []>) =
1129+ let semaphore = new SemaphoreSlim( throttle)
1130+ let throttleTask ( t : unit -> Task < 'a >) () : Task < 'a > =
1131+ task {
1132+ do ! semaphore.WaitAsync() |> ToTaskUnit
1133+ let! result = Catch <| t()
1134+ semaphore.Release() |> ignore
1135+ return match result with
1136+ | Choice1Of2 r -> r
1137+ | Choice2Of2 e -> raise e
1138+ }
1139+ tasks
1140+ |> Seq.map throttleTask
1141+ |> Parallel
1142+ #endif
0 commit comments