我遇到的问题似乎与任务创建有关。在使用循环填充任务数组并在单独的循环中启动它之后,我的结果虽然一致,但却是错误的。但是,如果我单独填充数组,在循环内启动每个任务,一切都很好。任何人都可以给我一些建议吗?
例如,这是有问题的:
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();
答案 0 :(得分:6)
问题是你的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
并从temp
计算i
:
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();
}