c# - 将任务按完成顺序排序

标签 c# asynchronous task-parallel-library

大约一年前,我看到 Jon Skeet 做了一次演讲,他展示了一段 C# 5,它会获取任务列表并按任务完成的顺序返回它们。

它使用了 async/await 和 WhenAny,非常漂亮,但我终生不记得它是如何工作的。现在我需要它。

我希望弄清楚如何创建一个具有与此类似的签名的方法..

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

可以按如下方式使用:

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}));
}

我想出了以下方法,但感觉并不像我记得的那么简单

    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;
    }

有谁记得我提到的片段或如何改进它?

最佳答案

Jon Skeet , Stephen Toub , and I都有略微不同的方法。我的是 available via NuGet如果您不想自己编写。

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

关于c# - 将任务按完成顺序排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16938999/

相关文章:

json - 错误类型 '_InternalLinkedHashMap<String, dynamic>'不是 'String'类型的子类型

asynchronous - F# 中的 F# 连续循环

c# - Y型任务执行

c# - C#中如何绑定(bind)两个类的变量?

c# - 通用约束需要强制转换

c# - 如何创建更好看的 DataGridView?

ajax - Angular JS 数据未从异步 http 请求填充

ios - 创建一个外部网络服务并在 viewdidload 中调用它

c# - 链接 Task.Factory.FromAsync 和 ContinueWith 与等待

c# - ProcessStartInfo.EnvironmentVariables 和 ProcessStartInfo.Environment 之间有什么区别