问题
I am defining a jagged array of threads (such that each thread can operate on the directory tree of its own) in this manner
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]);
}
But in calculate i always get value of j >= FilesDir[i].Length . I have also checked that objects are passed by value except arrays. What could be a workaround for this and what could be the reason for this behavior?
PS. Introducing a shared lock might help in mitigation the concurrency issue but i want to know about the reason for such behavior.
回答1:
But in calculate i always get value of j >= FilesDir[i].Length
This isn't a concurrency issue, as your for loop is executing on a single thread. This happens because the lambda expression is closing over your i and j variables. This effect is called Closure.
In order to avoid it, create a temp copy before passing both variables to Task.Run:
var tempJ = j;
var tempI = i;
threads[tempI][tempJ] = Task.Run(() =>
{
Calculate(tempI, tempJ, InstancesDir, FilesDir, PointSum);
});
来源:https://stackoverflow.com/questions/28315016/jagged-array-of-tasks-concurrency-issues