I am doing parallel programming using F#. With fixed number of elements, for example with 2 elements a1, a2 and a function f, I can do as follows:
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 () -> f a))
Task.WaitAll(ts)
List.map (fun (t: Task<_>) -> t.Result) ts
Visual Studio spots that Task.WaitAll couldn't accept Task< T > list as its parameter. Task.WaitAll can have Task [] as its argument but it makes no sense because I need to get Result for next computation.
As Robert explains, if you want to call
WaitAll
, you'll have to cast the elements sequence to the base typeTask
and then convert it to an array. You can define your extension member forTask
to make the tas simpler:I'm using array comprehension and cast instead of
Seq.cast
becauseSeq.cast
takes untypedIEnumerable
- so F# infers better type for the extension method.Another option is not to call
WaitAll
at all - if you don't do it, theResult
properties will block until a task completes. This means that you'll block the thread anyway (there may be a bit larger number of blockings, but I'm not sure if it affects performance too much). If you useList.map
to collect all results, the behavior would be almost the same.