Open TonyValenti opened 2 years ago
Tagging subscribers to this area: @dotnet/area-system-threading-tasks See info in area-owners.md if you want to be subscribed.
Author: | TonyValenti |
---|---|
Assignees: | - |
Labels: | `api-suggestion`, `area-System.Threading.Tasks`, `untriaged` |
Milestone: | - |
Isn't this scenario covered by the Task.WaitAsync
method?
await Task.WhenAll(T1, T2).WaitAsync(token);
@theodorzoulias I think so.
But should we stay consistent with Task.WaitAll
and Task.WaitAny
?
Because these accept a CancellationToken
.
I'm currently just not sure for what reason this makes sense implementation-wise.
Yes we could check for cancellation in TaskFactory.CommonCWAnyLogic
but is that good? I don't know.
@deeprobin a disadvantage of using the Task.WhenAll
+WaitAsync
combination is that the continuations attached to the tasks are (most probably) not detached when the token is canceled. So if it's called repeatedly in a loop, and the tasks are long running, a serious memory leak might emerge.
Hard to imagine a scenario where someone would need to do something like this though.
a disadvantage of using the Task.WhenAll+WaitAsync combination is that the continuations attached to the tasks are (most probably) not detached when the token is canceled
How would the behavior of Task.WhenAll(tasks, CT)
overload differ here?
CancellationToken
uses a cooperative approach, so the work the Task
represents would have to react to the cancellation token and stop itself. Task.WhenAll
can't force an arbitrary task to abort.
How would the behavior of
Task.WhenAll(tasks, CT)
overload differ here?
@MihaZupan absolutely no behavioral difference. the Task.WhenAll(tasks, token)
would behave exactly the same with the Task.WhenAll(tasks).WaitAsync(token)
. The only difference would be in the memory consumption after a canceled await
. The GC.GetTotalMemory(true)
would return a smaller number.
the continuations attached to the tasks are (most probably) not detached when the token is canceled
They're not. They can't be. If they were, it would break a use like:
Task t = Task.WhenAll(t1, t2);
while (true)
{
try
{
await t.WaitAsync(pollInterval);
break;
}
catch {}
... // do something
}
as the continuations the WhenAll hooked up to t1 and t2 would then be removed when the first WaitAsync fails, after which point t
would never complete.
Background and motivation
Currently there is no way to cancel a Task.WhenAll(..). It would be great if the current overloads also accepted a cancellation token.
API Proposal
API Usage
Alternative Designs
None that I can think of.
Risks
None