Task.WaitAll listed in F #

I am doing parallel programming with F #. With a fixed number of elements, for example, with two elements a1, a2 and function f, I can do the following:

let t1 = Task.Factory.StartNew(fun () -> f a1) let t2 = Task.Factory.StartNew(fun () -> f a2) Task.WaitAll(t1, t2) t1.Result, t2.Result 

I wonder how I could do the same with a list of elements:

 let ts = List.map (fun a -> Task.Factory.StartNew(fun () -> fa)) Task.WaitAll(ts) List.map (fun (t: Task<_>) -> t.Result) ts 

Visual Studio notes that Task.WaitAll cannot accept Task <T> as a parameter. Task.WaitAll may have Task [] as an argument, but that doesn't make sense, because I need to get the result for the next calculation.

+4
source share
3 answers

As Robert explains, if you want to call WaitAll , you will need to cast the sequence of elements to the base type of Task , and then convert them to an array. You can define your extension member for Task to simplify tas:

 type System.Threading.Tasks.Task with static member WaitAll(ts) = Task.WaitAll [| for t in ts -> t :> Task |] 

I use array understanding and instead of Seq.cast instead of Seq.cast , because Seq.cast accepts untyped IEnumerable - so F # indicates the best type for the extension method.

Another option is to not call WaitAll at all - if you do not, the Result properties will be blocked until the task completes. This means that you will block the thread anyway (there might be a bit more locks, but I'm not sure if this affects the performance too much). If you use List.map to collect all the results, the behavior will be almost the same.

+5
source

This is an unsuccessful project. Task.WaitAll uses the C # params keyword so that you can specify multiple arguments and have them in an array in a method. It also uses C # implicit casting so you can give it a Task<T> . In F # you have to do it yourself, explicitly pronouncing and converting to an array:

 let ts = [| Task.Factory.StartNew(fun () -> 1) Task.Factory.StartNew(fun () -> 2) |] Task.WaitAll(ts |> Seq.cast<Task> |> Array.ofSeq) 

Now you can get the results from ts .

+3
source

The array also has a map, so there is no reason why you cannot put tasks into the array.

Or you can convert to an array just for waitall ...

+1
source

Source: https://habr.com/ru/post/1341281/


All Articles