c# task 作用于以后的引用

c# task acting on later reference

for(int i = 0; i < list.Count(); i++)
{
  Task task = new Task(() => DoWork(list[i]));
  task.Start();
}

谁能告诉我如何确保 DoWork 函数作用于列表中 i 的位置?

我遇到了一个问题,任务将在 for 循环的下一次迭代后的某个时间点开始,所以我基本上得到了重复的线程。

是的,变量 被 lambda 表达式捕获,然后您正在修改它。有几个简单的选项:

首先,将变量复制到循环中实例化的变量:

for (int i = 0; i < list.Count; i++)
{
    int copy = i;
    Task task = new Task(() => DoWork(list[copy]));
    task.Start();
}

现在每次迭代都会捕获一个不同的 copy 变量,该变量不会在其他地方被修改。

其次,引入局部变量但用list[i]代替:

for (int i = 0; i < list.Count; i++)
{
    var item = list[i];
    Task task = new Task(() => DoWork(item));
    task.Start();
}

第三, 如果您使用的是 C# 5 或更高版本,则使用 foreach:

foreach (var item in list)
{
    Task task = new Task(() => DoWork(item));
    task.Start();
}

在早期版本的 C# 中,会出现与原始代码相同的问题,因为单个 item 变量会在每次迭代中发生变化。从 C# 5 开始,foreach 循环的每次迭代都会引入一个新的迭代变量。

附带说明一下,从 .NET 4.5 开始,使用 Task.Run 通常更简单,而不是创建一个新任务然后启动它。