5

Jon Skeet が 1 年ほど前に講演を行ったのを見ました。そこで彼は、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;
    }

私が言及しているスニペット、またはこれをどのように改善できるかを知っている人はいますか?

4

1 に答える 1