Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/268.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Task.WhenAll(IEnumerable):任务启动两次?_C#_Async Await - Fatal编程技术网

C# Task.WhenAll(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

我刚刚偶然发现了的一个重载,它以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 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();