问题描述
我定义线程的交错数组(这样每个线程都可以在自己的目录树操作)以这种方式
任务[] []线程=新任务[InstancesDir.Length] [];
的for(int i = 0; I< InstancesDir.Length;我++)
{
线程[我] =新任务[InstancesDir [I] .Length]。
}
的for(int i = 0; I< FilesDir.Length;我++)
{
对于(INT J = 0; J< FILESDIR [I] .Length; J ++)
{
螺纹[I] [J] = Task.Run(()=>
{
计算(I,J,InstancesDir,FILESDIR,PointSum);
});
}
Task.WaitAll(线程[I]);
}
但在计算我总是得到的J值> = FILESDIR [I] .Length。我还检查的对象是按值传递除数组。什么可能是一个解决方法,这有什么能为这种现象的原因是什么?
PS。引入一个共享锁可能会缓解并发性问题,帮助,但我想知道这种行为的原因。
这是不是并发问题,因为你的为
循环执行在单个线程。这是因为拉姆达EX pression是收了你的我
和Ĵ
变量。这种效应被称为的关闭的。
为了避免它,创建一个临时副本,这两个变量传递给前 Task.Run
:
VAR tempJ = j的;
VAR TEMPI =我;
螺纹[TEMPI] [tempJ] = Task.Run(()=>
{
计算(TEMPI,tempJ,InstancesDir,FILESDIR,PointSum);
});
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.
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);
});
这篇关于任务铁血阵列 - 并发问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!