为什么并行任务不运行?

问题描述 投票:-1回答:2

我有这段代码,它是简化功能以证明问题的骨架:

        var tasks = Enumerable.Range(0, 10)
            .Select(laneNo => Task.Run(() => Console.WriteLine($"Starting generator for lane {laneNo}")));

        for(int r=0; ;++r)
        {
            Task.Delay(TimeSpan.FromSeconds(3)).Wait();

            Console.WriteLine($"Iteration {r} at {DateTime.Now}");
        }

我从没见过将“启动生成器”打印到控制台,但我确实看到每3秒执行一次迭代-某种原因导致这些任务无法进行(在真实代码中,它们运行了相当长的一段时间,但是删除不会影响到问题)。

为什么第一批任务未运行?我的理论是和Task.Delay有关吗?

c# task-parallel-library
2个回答
1
投票

您的linq语句永远不会实现。诸如Select,Where,OrderBy之类的Linq运算符可作为构建块链接在一起,但直到您通过foreach运行它或使用不返回可枚举的运算符(例如ToArray,ToList,First,Last等)时,它们才被执行。

如果在末尾调用ToList,应该会看到所有任务正在执行,但是如果仅调用First,则应该只看到一个任务,因为原始Range的迭代将在第一个元素之后终止。


0
投票

LINQ Select已推迟执行;它仅定义一个迭代器,因此不会生成您的Task

您可以使用Task.WhenAll(IEnumerable<Task>),它将迭代并等待每个Task.WhenAll(IEnumerable<Task>),生成新的Task,一旦提供的所有任务也都完成,该Task将完成:

var tasks = Enumerable.Range(0, 10)
        .Select(laneNo => Task.Run(() => Console.WriteLine($"Starting generator for lane {laneNo}")));

await Task.WhenAll(tasks);
© www.soinside.com 2019 - 2024. All rights reserved.