我有这段代码,它是简化后的较大功能的框架,以证明问题所在:
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
有关吗?
答案 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>