通过for循环创建任务与单独创建任务不同
本文关键字:创建 任务 单独 for 通过 循环 | 更新日期: 2023-09-27 18:30:01
我遇到的问题似乎与任务创建有关。在使用循环填充任务数组,并在单独的循环中启动它们之后,我的结果虽然一致,但却是错误的。然而,如果我单独填充数组,在循环中启动每个任务,一切都很好。有人能给我一些建议吗?
例如,这是有问题的:
int c = 1;
for (int i = 1; i <= 4; i++)
{
taskArray[i-1] = new Task(() => calculateRows(c, true));
c = c + 2;
}
foreach (Task t in taskArray) t.Start();
但这很好:
taskArray[0] = new Task(() => calculateRows(1, true));
taskArray[1] = new Task(() => calculateRows(3, true));
taskArray[2] = new Task(() => calculateRows(5, true));
taskArray[3] = new Task(() => calculateRows(7, true));
foreach (Task t in taskArray) t.Start();
问题是lambda表达式捕获c
-变量c
,而不是它在创建任务时的值。因此,当您开始执行任务时,c
将为9。即使在循环中启动它们,也不能保证lambda表达式中的代码在更改为c
之前会开始执行。
为了解决这个问题,您可以为循环的每次迭代使用一个单独的局部变量:
int c = 1;
for (int i = 1; i <= 4; i++)
{
int temp = c;
taskArray[i-1] = new Task(() => calculateRows(temp, true));
c = c + 2;
}
foreach (Task t in taskArray)
{
t.Start();
}
或者完全绕过c
,从i
:计算temp
for (int i = 1; i <= 4; i++)
{
int temp = i * 2 - 1;
taskArray[i-1] = new Task(() => calculateRows(temp, true));
}
foreach (Task t in taskArray)
{
t.Start();
}
你需要这些都是单独的任务吗?你能用Parallel.For
代替吗?或者可能是评论中建议的Enumerable.Range
:
var tasks = Enumerable.Range(1, 4)
.Select(x => new Task(() => calculateRows(x * 2 - 1, true)
.ToArray();
foreach (Task t in tasks)
{
t.Start();
}