为什么并行任务没有运行?

时间:2020-04-21 17:21:21

标签: c# task-parallel-library

我有这段代码,它是简化后的较大功能的框架,以证明问题所在:

        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有关吗?​​

2 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

LINQ Select已推迟执行;它只是定义了一个迭代器,因此不会生成您的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); 就会完成:

 <head>
    <script>
        $(document).ready(function() {
            var timeSlots = ["00:00:00", "00:30:00", "01:00:00", "01:30:00", "02:00:00", "02:30:00", 
                            "03:00:00", "03:30:00", "04:00:00", "04:30:00", "05:00:00", "05:30:00", 
                            "06:00:00", "06:30:00", "07:00:00", "07:30:00", "08:00:00", "08:30:00", 
                            "09:00:00", "09:30:00", "10:00:00", "10:30:00", "11:00:00", "11:30:00", 
                            "12:00:00", "12:30:00", "13:00:00", "13:30:00", "14:00:00", "14:30:00", 
                            "15:00:00", "15:30:00", "16:00:00", "16:30:00", "17:00:00", "17:30:00", 
                            "18:00:00", "18:30:00", "19:00:00", "19:30:00", "20:00:00", "20:30:00", 
                            "21:00:00", "21:30:00", "22:00:00", "22:30:00", "23:00:00", "23:30:00"];

            //alert();

            for (var i = 0; i < timeSlots.length; i++) {
                $("#tblTimeSlot").append('<tr></tr>');
                $("#tblTimeSlot tr:last").append('<td>' + timeSlots[i-1] + '</td>');

                if (i > 0 && i % 6  == 0){
                    $("#tblTimeSlot tbody").append('<tr></tr>');
                    $("#tblTimeSlot tbody tr:last").append('<td>' + timeSlots[i-1] + '</td>');
                }
            }
        });
    </script>
</head>
<body>
    <table id="tblTimeSlot" border=1>
    </table>
</body>