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

C# for循环初始化Task时参数传递错误及文件访问冲突问题

问题成因

这个问题的核心是C#中闭包对循环变量的捕获特性导致的:

  • C# for循环中声明的迭代变量i在整个循环的生命周期内是同一个变量实例,你在lambda表达式() => newMethodForThreads(i)中直接引用i时,捕获的是i的引用,而非当前迭代的i的具体值。
  • Task.Factory.StartNew创建的任务不会立刻执行,会被调度到线程池等待运行。等到任务实际执行、读取i的值时,for循环大概率已经推进到后续迭代甚至已经结束,此时i的值已经被更新为后续迭代值,或是循环结束后的x+1。

这就直接导致两个你观察到的异常现象:

  1. 多个任务拿到相同的i值,同时往同一个Threadedfile{i}.txt写入,触发文件被其他线程占用的IO异常
  2. 部分迭代的i值还没被任务读取就被覆盖,出现“迭代值被跳过”的情况
修复方案

只需要在循环内部声明一个局部临时变量,接收当前迭代的i值,再在lambda中引用这个局部变量即可。每次迭代都会生成独立的临时变量实例,闭包捕获的是对应迭代的独立变量,不会出现值被覆盖的问题:

public static List<Task> createTasks(int x)
{
    List<Task> taskList = new List<Task>();
    for (int i = 1; i <= x; i++)
    {
        int temp = i;
        taskList.Add(Task.Factory.StartNew(() => newMethodForThreads(temp)));
    }
    return taskList;
}

public static void newMethodForThreads(int i)
{
    File.WriteAllLines($"C:\\Users\\my_username\\Desktop\\Shenanigans\\Threadedfile{i}.txt", list);
    Console.WriteLine($"File Threadedfile{i}.txt finished.");
}

补充说明:从C# 5.0开始,foreach循环的迭代变量已经调整为每次迭代生成新实例,不会存在这个捕获问题,但for循环的规则至今没有变更,依然是全局共享同一个迭代变量实例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 18:51:03