执行后续引用的 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
循环的下一次迭代后的某个时候开始,所以我基本上得到了重复的线程。
是的,变量由 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
通常更简单,而不是创建新任务然后启动它。