Suppose I have the following:
IEnumerable<Task<TimeSpan>> tasks = //...
TimeSpan[] results = await Task.WhenAll(tasks);
// Handle results
By the time I can handle the results all the task must have finished.
Is there a way to handle each result on demand?
Like registering a delegate / callback that will get executed when a task is completed:
IEnumerable<Task<TimeSpan>> tasks = //...
await Task.WhenAll(tasks, result =>
{
// A task has finished. This will get executed.
// result is of type TimeSpan
});
Is there a way to handle each result on demand?
Yes, you use WhenAny
instead of WhenAll
... or call ContinueWith
on each task.
For example, for the WhenAny
approach:
ISet<Task<TimeSpan>> tasks = new HashSet<Task<TimeSpan>>(...);
while (tasks.Count != 0)
{
var task = await Task.WhenAny(tasks);
// Use task here
tasks.Remove(task);
}
There's another option you could use, where you transform the original sequence of tasks into a sequence of tasks which completes in order, but giving the same results. Details are in this blog post, but the result is that you can use:
foreach (var task in tasks.InCompletionOrder())
{
var result = await task;
// Use the result
}
See more on this question at Stackoverflow