执行后续引用的 C# 任务

本文关键字:任务 引用 执行 | 更新日期: 2023-09-27 18:27:18

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

有人可以告诉我如何确保DoWork功能将在位置i的列表中起作用吗?

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

执行后续引用的 C# 任务

是的,变量由 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 通常更简单,而不是创建新任务然后启动它。