I saw how John Skeet spoke about a year ago, where he showed a C # 5 fragment that took a list of tasks and returned them in the order in which they were completed.
He used async / await and WhenAny and was pretty handsome, but I can't let my life remember how it worked. Now I need this.
I hope to find out how to create a method with a similar signature.
Task<IEnumerable<T>> InOrderOfCompletion<T>(IEnumerable<T> tasks) where T : Task
And can 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 came up with the following, but it is not as easy 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; }
Does anyone remember if you know the snippet I'm referring to, or how can this be improved?