参差不齐的任务数组 - 并发问题
Jagged array of tasks - Concurrency Issues
我正在以这种方式定义一个交错的线程数组(这样每个线程都可以在自己的目录树上操作)
Task[][] threads = new Task[InstancesDir.Length][];
for (int i = 0; i < InstancesDir.Length; i++)
{
threads[i] = new Task[InstancesDir[i].Length];
}
for (int i = 0; i < FilesDir.Length; i++)
{
for (int j = 0; j < FilesDir[i].Length; j++)
{
threads[i][j] = Task.Run(() =>
{
Calculate(i, j, InstancesDir, FilesDir, PointSum);
});
}
Task.WaitAll(threads[i]);
}
但是在计算中我总是得到 j >= FilesDir[i].Length 的值。我还检查了对象是否按值传递,数组除外。有什么解决方法可以解决此问题?此行为的原因可能是什么?
PS。引入共享锁可能有助于缓解并发问题,但我想知道这种行为的原因。
But in calculate i always get value of j >= FilesDir[i].Length
这不是并发问题,因为您的 for
循环是在单个线程上执行的。发生这种情况是因为 lambda 表达式正在关闭您的 i
和 j
变量。这个效果叫做Closure.
为了避免这种情况,在将两个变量传递给 Task.Run
之前创建一个临时副本:
var tempJ = j;
var tempI = i;
threads[tempI][tempJ] = Task.Run(() =>
{
Calculate(tempI, tempJ, InstancesDir, FilesDir, PointSum);
});
我正在以这种方式定义一个交错的线程数组(这样每个线程都可以在自己的目录树上操作)
Task[][] threads = new Task[InstancesDir.Length][];
for (int i = 0; i < InstancesDir.Length; i++)
{
threads[i] = new Task[InstancesDir[i].Length];
}
for (int i = 0; i < FilesDir.Length; i++)
{
for (int j = 0; j < FilesDir[i].Length; j++)
{
threads[i][j] = Task.Run(() =>
{
Calculate(i, j, InstancesDir, FilesDir, PointSum);
});
}
Task.WaitAll(threads[i]);
}
但是在计算中我总是得到 j >= FilesDir[i].Length 的值。我还检查了对象是否按值传递,数组除外。有什么解决方法可以解决此问题?此行为的原因可能是什么?
PS。引入共享锁可能有助于缓解并发问题,但我想知道这种行为的原因。
But in calculate i always get value of j >= FilesDir[i].Length
这不是并发问题,因为您的 for
循环是在单个线程上执行的。发生这种情况是因为 lambda 表达式正在关闭您的 i
和 j
变量。这个效果叫做Closure.
为了避免这种情况,在将两个变量传递给 Task.Run
之前创建一个临时副本:
var tempJ = j;
var tempI = i;
threads[tempI][tempJ] = Task.Run(() =>
{
Calculate(tempI, tempJ, InstancesDir, FilesDir, PointSum);
});