将任务排序为完成顺序

我看到Jon Skeet在大约一年前发表演讲,他展示了一个C#5的片段,它将获取一系列任务并按照他们完成的顺序返回它们。

它使用了async / await和WhenAny并且很漂亮,但我不能为我的生活记住它是如何工作的。 现在我需要它。

我希望弄清楚如何使用类似于此的签名创建方法。

Task<IEnumerable> InOrderOfCompletion(IEnumerable tasks) where T : Task 

可以使用如下:

 public async Task DelayedInt(int i) { await Task.Delay(i*100); return i; } [Test] public async void Test() { Task[] tasks = new[] {5, 7, 1, 3, 2, 6, 4}.Select(DelayedInt).ToArray(); IEnumerable<Task> ordered = await InOrderOfCompletion(tasks); Assert.That(ordered.Select(t => t.Result).ToArray(), Is.EqualTo(new [] {1,2,3,4,5,6,7})); } 

我想出了以下内容,但感觉并不像我记得那么简单

  async Task<IEnumerable> InOrderOfCompletion(IEnumerable tasks) where T : Task { HashSet taskSet = new HashSet(tasks); List results = new List(); while(taskSet.Count > 0) { T complete = (T) await Task.WhenAny(taskSet); taskSet.Remove(complete); results.Add(complete); } return results; } 

有人记得知道我所指的片段或如何改进吗?

Jon Skeet , Stephen Toub 和我的方法略有不同。 如果您不想自己编写,我可以通过NuGet获取 。

实际上,关键是要避免 Task.WhenAny因为这会将算法从O(N)转换为O(N ^ 2)。