参差不齐的任务数组 - 并发问题

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 表达式正在关闭您的 ij 变量。这个效果叫做Closure.

为了避免这种情况,在将两个变量传递给 Task.Run 之前创建一个临时副本:

var tempJ = j;
var tempI = i;

threads[tempI][tempJ] = Task.Run(() =>
{
    Calculate(tempI, tempJ, InstancesDir, FilesDir, PointSum);
});