Description
openedon Sep 21, 2017
Currently, when I have a number of Task
instances where I want to perform aggregate operations across all of them (waiting for all of them to complete, for any of them to complete, etc.), I like to use the static WhenAll
, WhenAny
, etc. methods.
I also like to use ValueTask<T>
as well for areas where I don't need the heap allocation that a Task<T>
brings.
That said, I can't currently use WhenAll
, WhenAny
, etc. because they take sequences of Task<T>
. While there are workarounds, all of them fall short in some way:
- I could call
AsTask
, but then that allocates aTask<T>
and call the existing methods onTasks
but the allocations is the situation I was trying to avoid in the first place. - I could write my own, but the coreclr implementation is quite robust, and I'd certainly miss situations that are coded for in there.
This specific example is for ValueTask<T>
but it really applies to any awaitable type.
I also think we'd need a new signature for WhenAny
; the current implementation returns a Task
, and the pattern to figure out which task finished is to do an equality comparison on the reference returned. I don't really agree that checking the result as ValueTask<T>
does is the right way (imagine waiting on signals for true
/false
results from multiple votes, checking equality on the result won't work here).