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