对于线程安全计数,请使用 Interlocked 方法:System.Threading.Interlocked.Increment(ref globalID)
private static int globalID;
// Be very careful about using a property to expose the counter
// do not *use* this value directly, but can be useful for debugging
// instead use the return values from Increment, Decrement, etc.
public int UnsafeGlobalID { get { return globalID; } }
注意:您需要为ref
. 可以通过属性公开字段,但在代码中可能会出现问题。最好使用互锁方法,例如围绕需要以同步方式获取值的逻辑的Interlocked.CompareExchange
显式语句。,等lock
的返回值通常应该在逻辑中使用。Increment
Decrement
我的问题与柜台有关。我不知道如何在多个线程中管理该计数器。如果我将它作为变量传递给函数,我相信我会有一个不准确的较低/使用的数字离开递归循环。全局变量确保下一个数字高于前一个数字。
如果我有多个线程的计数器的起始位置不同,我该如何确保这个线程安全?我目前看到的唯一方法是手动编写同一函数和计数器的多个版本并使用TaskFactory
递归调用MyFunction(newClass, ID)
的值为ID
,但我不确定If (thisClass.IsPropertyValueAboveZero)
应该做什么。是为了确保您有一个非零起点吗?如果是这样,最好在此函数之外的初始调用之前确保它是非零的。
此外,foreach 循环中的逻辑对我来说也没有意义。在willMyClass newClass = new MyClass(GlobalID, ID)
是ID
参数值,或者如果IsPropertyValueAboveZero
为真,它将是 的当前值GlobalID
。所以ID
通常会小于GlobalID
因为在循环GlobalID
之前递增。foreach
我认为您在GlobalID
不需要时会通过。
// if IsPropertyValueAboveZero is intended to start above zero
// then you can just initialize the counter to 1
private static int globalID = 1;
public void MyFunction(myClass thisClass, int id)
{
// ListOfMyClass and ListOfClasses are probably not thread-safe
// and you may need to add locks around the Add and get a copy
// of ListOfClasses before the foreach enumeration
// You may want to look at https://stackoverflow.com/a/6601832/29762
ListOfMyClass.Add(thisClass);
foreach (class someClass in ListOfClasses)
{
int newId = System.Threading.Interlocked.Increment(ref globalID);
MyClass newClass = new MyClass(newId);
MyFunction(newClass, newId); //Recursive Call
}
}