将任务排序为完成顺序
我看到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)。