【发布时间】:2018-02-24 17:42:41
【问题描述】:
在使用一个名为GlobalID 的全局整数作为计数器时,
以下代码工作正常:
MyFunction(myClass thisClass, Int ID)
{
ListOfMyClass.add(thisClass)
If (thisClass.IsPropertyValueAboveZero)
{
ID = GlobalID;
}
GlobalID++;
Foreach (class someClass in ListOfClasses)
{
MyClass newClass = new MyClass(GlobalID, ID)
MyFunction(newClass, ID) //Recursive Call
}
}
我基本上使用GlobalID 作为每次调用函数时的递增计数器。计数器在第一次执行时被分配一个起始位置。我正在使用全局变量,因为我想确保每次传递的 ID 都准确增加,而不管执行是否进入或离开递归调用。这个函数(第一次......)从分配全局变量开始位置的 ForEach 循环中调用
我的目标是使用 Parallel.ForEach 进行初始调用,而不是使用常规的 For Each 循环。我的问题与柜台有关。我不知道如何在多个线程中管理该计数器。如果我将它作为变量传递给函数,我相信我会有一个不准确的较低/使用的数字离开递归循环。全局变量确保下一个数字高于前一个数字。 thisClass.IsPropertyValueAboveZero 只是基于条件语句描述动作的任意方式。它对其余代码没有有意义的引用。
如果我有多个线程,它们的计数器的起始位置不同,我该如何确保这个线程安全?我目前看到的唯一方法是手动编写同一函数和计数器的多个版本并使用TaskFactory
【问题讨论】:
-
我看到了
Interlocked.Increment,最终我会需要它,但问题是该计数器有多个实例,并确保每次通过时它都会增加,尤其是在离开递归问题时 -
@mjwills 这将防止竞争条件,但如果您希望线程维护可能相互偏移的独立计数器,则无济于事。
-
Interlocked.Increment适用于递增GlobalID,但大概您不希望在这一行出现重复:ID = GlobalID;,因此您将锁定整个块。 -
@JasonR。假设这项工作是批处理的而不是连续传入的,您可以为每个线程维护一个单独的计数器,并在您加入所有线程时聚合计数。
-
@JasonR。如果您不知道自己真正想要实现什么,则很难建议正确的实施(因此它使帖子不太适合 SO,也可以以回答标题的方式回答,可能对您的情况没有帮助- 这有点发生了)......瑞安和我的回答,它应该向您展示您将面临的问题,但我认为我们的任何一个答案都不能直接适用于您的样本(也都回答了标题中的问题) .
标签: c# multithreading recursion task-parallel-library taskfactory