C# Task.WhenAll(IEnumerable):任务启动两次?
我刚刚偶然发现了的一个重载,它以IEnumerable作为参数C# Task.WhenAll(IEnumerable):任务启动两次?,c#,async-await,C#,Async Await,我刚刚偶然发现了的一个重载,它以IEnumerable作为参数 public static Task WhenAll(IEnumerable<Task<TResult>> tasks) 结果如下: Create the task enumerators... Done! Start Tasks and wait Start task 1 This is the first time this task runs Start task 2 This is the firs
public static Task WhenAll(IEnumerable<Task<TResult>> tasks)
结果如下:
Create the task enumerators... Done!
Start Tasks and wait
Start task 1 This is the first time this task runs
Start task 2 This is the first time this task runs
Start task 3 This is the first time this task runs
Finished task 2
Finished task 3
Finished task 1
Finished waiting. Results:
Start task 1 This task has been run before
Finished task 1
1
Start task 2 This task has been run before
Finished task 2
2
Start task 3 This task has been run before
Finished task 3
3
显然每个任务运行两次我做错了什么
更奇怪的是:如果我在任务之前使用
ToList()
枚举任务序列,那么函数就会按预期工作 您的问题是推迟执行。换行
IEnumerable<Task<int>> tasks = Enumerable.Range(1, 3)
.Select(i => Calculate(i));
Select()
不会立即执行“查询”,而是返回一个枚举数。仅当使用此枚举器迭代任务时,才会为序列1…3调用内部lambda。在您的版本中,每次迭代
任务
,都会再次调用计算(i)
,并创建新任务。使用
.ToList()
枚举器执行一次,生成的任务序列
存储在列表
中(第二次枚举该列表时不再生成)
当您调用
Task.whalll(tasks)
时,此方法迭代任务
,从而启动每个任务。稍后再次迭代(使用foreach
循环输出结果)时,将再次执行查询,从而启动新任务。“请注意,此函数不是异步的,也不是可等待的”-它是可等待的。函数不必标记为async
即可等待-它只需返回遵循等待等待器模式的内容。而Task
是该模式的海报子项。spry,这是我的第一个版本。后来我意识到这可能是问题所在,我将所有内容都更改为异步等待。正如我在问题末尾所写,你的解决方案确实有效。然而,使用延迟执行,我希望它在Task.Whenall枚举序列时执行,显然Task.Whenall枚举两次。Task.Whenall
执行一次,然后在for
循环中再次执行。“然后再执行一次”-嗯,枚举器再次执行…:)
Create the task enumerators... Done!
Start Tasks and wait
Start task 1 This is the first time this task runs
Start task 2 This is the first time this task runs
Start task 3 This is the first time this task runs
Finished task 2
Finished task 3
Finished task 1
Finished waiting. Results:
Start task 1 This task has been run before
Finished task 1
1
Start task 2 This task has been run before
Finished task 2
2
Start task 3 This task has been run before
Finished task 3
3
IEnumerable<Task<int>> tasks = Enumerable.Range(1, 3)
.Select(i => Calculate(i));
var tasks = Enumerable.Range(1, 3)
.Select(i => Calculate(i)).ToList();