You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中for循环添加Task全部输出6、foreach添加Task正常的原因求解

问题原因分析

核心是C#的闭包变量捕获规则在for和foreach循环中的表现不同导致的:

1. for循环输出全为6的原因

  • for循环中声明的迭代变量i,在整个循环生命周期内仅存在同一个实例,所有Task.Run传入的lambda表达式捕获的都是这同一个i变量,而非循环执行到对应位置时i的瞬时值。
  • Task.Run创建的任务不会立刻执行,会等待线程池调度。而for循环执行速度远快于任务调度速度,等循环退出时,i已经完成最后一次自增变成6(循环退出条件为i < 6不成立,此时i的值就是6),所有任务启动后读取到的i都已经是6,因此输出全为6。

2. foreach循环结果符合预期的原因

  • C# 5.0及更高版本对foreach循环的捕获规则做了调整:每次循环迭代的item变量都是全新的独立实例,每个lambda捕获的都是对应迭代专属的item变量,和其他迭代的item互不干扰。
  • 因此就算任务延后执行,读取到的也是当前迭代对应数组元素的值,仅因任务调度顺序不固定,输出顺序和数组原始顺序不同,值都是正确的。
修复for循环问题的方案

在for循环体内声明临时变量存储当前迭代的i值,让lambda捕获这个临时变量即可:

var tasks = new List<Task>();
for (int i = 1; i < 6; i++)
{
    // 每次迭代生成独立的临时变量,lambda捕获的是该次迭代的临时变量
    var current = i;
    tasks.Add(Task.Run(() => Console.WriteLine(current)));
}
Task.WaitAll(tasks.ToArray());

内容的提问来源于stack exchange,提问作者kalka79

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 02:48:05