【发布时间】:2021-05-15 09:55:13
【问题描述】:
我有下面的代码。 (忽略FindPhysicalPdfTicketAsync的内部细节,内部包含await/awaitable)
IEnumerable<Task> findPhysicalPdfTicketTasks = irTable.ToList().Select(row =>
{
return FindPhysicalPdfTicketAsync(row,
ticketListUserControl.physicalPdfTicketExistsStatus);
});
除非我在上述代码之后的一行中调用Task.WhenAll(findPhysicalPdfTicketTasks) 或await Task.WhenAll(findPhysicalPdfTicketTasks),否则枚举中的任务永远不会执行。
作为测试,我在枚举之外独立运行了FindPhysicalPdfTicketAsync 方法,并且任务执行良好。
例如
IEnumerable<Task> test = irTable.First();
FindPhysicalPdfTicketAsync(test, ticketListUserControl.physicalPdfTicketExistsStatus);
那么,为什么可枚举的需要Task.WhenAll?
更新:我的问题在我发布后续内容之前已经结束:
那么是什么原因导致Task.WhenAll(findPhysicalPdfTicketTasks) 触发枚举呢?我的理解是WhenAll() 所做的只是等待所有“假定已经在运行”的任务完成。
【问题讨论】:
-
在
Select之后添加ToList和返回语句的结尾,这样你的枚举就实现了。否则它会被懒惰地评估。 -
因为延迟执行。
-
Select()仅返回一个投影承诺,在您枚举其结果之前它不会执行其中的表达式。 -
两件事。 1. 我知道惰性/延迟行为。我正在查看我的代码的 irTable.ToList() 部分,并认为这应该已经引起了枚举。我并没有意识到我需要另一个 .ToList 来“再次”触发 select 语句的枚举。我的错,我错过了。
-
K.Carter Sr.
Task.WhenAll在提供IEnumerable<Task>参数时,通过枚举它立即实现可枚举,并将实现的任务存储到List<Task>。你可以研究它的源代码here。
标签: c# multithreading asynchronous async-await task-parallel-library