I saw Jon Skeet give a talk a year or so ago where he showed a snippet of C# 5 that would take a list of Tasks and return them in the order they completed.
It made use of async/await and WhenAny and was quite beautiful but I can't for the life of me remember how it worked. Now I have need for it.
I'm hoping to figure out how to create a method with a signature similar to this..
Task<IEnumerable<T>> InOrderOfCompletion<T>(IEnumerable<T> tasks) where T : Task
And could be used as follows:
public async Task<int> DelayedInt(int i)
{
await Task.Delay(i*100);
return i;
}
[Test]
public async void Test()
{
Task<int>[] tasks = new[] {5, 7, 1, 3, 2, 6, 4}.Select(DelayedInt).ToArray();
IEnumerable<Task<int>> ordered = await InOrderOfCompletion(tasks);
Assert.That(ordered.Select(t => t.Result).ToArray(), Is.EqualTo(new [] {1,2,3,4,5,6,7}));
}
I've come up with the following but it doesn't feel as simple as I remember
async Task<IEnumerable<T>> InOrderOfCompletion<T>(IEnumerable<T> tasks) where T : Task
{
HashSet<Task> taskSet = new HashSet<Task>(tasks);
List<T> results = new List<T>();
while(taskSet.Count > 0)
{
T complete = (T) await Task.WhenAny(taskSet);
taskSet.Remove(complete);
results.Add(complete);
}
return results;
}
Do anyone remember know the snippet I'm referring to or how this can be improved upon?