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

C# Parallel.Invoke执行Action列表时所有调用参数均为10问题排查

问题原因

该问题是C#中典型的循环变量闭包捕获问题,核心逻辑如下:

  • for循环中定义的迭代变量i的作用域覆盖整个循环周期,所有迭代全程复用同一个变量实例
  • 代码中Lambda表达式() => DoSomething(i)捕获的是i的引用,而非定义Lambda那一刻i的瞬时值
  • 循环完全执行结束后i的值已经迭代为10,后续Parallel.Invoke执行所有Lambda时,读取的都是这个已经变为10的同一个变量,因此所有调用的参数都是10

解决方法

在循环内部新增一个局部临时变量,存储当前迭代的i值,让Lambda捕获这个临时变量即可。每次迭代都会生成独立的临时变量实例,不会被后续迭代修改:

public static void Main()
{
    var actions = new List<Action>();
    for (int i = 0; i < 10; i++)
    {
        // 每次迭代创建独立的局部变量,Lambda捕获该变量不会被后续迭代覆盖
        int currentNum = i;
        actions.Add(() => DoSomething(currentNum));
    }
    
    Parallel.Invoke(actions.ToArray());
}

private static void DoSomething(int number)
{
    Console.WriteLine(string.Format("DoSomething number {0}", number));
    Thread.Sleep(5000);
}

补充说明:C# 5.0及以上版本已经优化了foreach循环的迭代变量捕获逻辑,foreach场景不会出现该问题,但for循环的逻辑未做调整,开发时需要注意规避该坑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 23:06:03