我知道int在内存中没有固定的位置所以它根本无法工作。但完全相同的代码部分将与不同的名称,参数e.t.c同时运行
我需要基本上传递一个“Name”字符串,然后以某种方式递增我的int数组中的一个项目。
Dictionary<string, int> intStats = new Dictionary<string, int>();
该字典根据作为字典字符串键提供的“名称”存储所有统计信息。
由于我使用了大量的多线程,我希望尽可能保持int count的同步。这就是为什么我试图使用Interlocked.Increment(ref intStats[theName]);
但不幸的是,这不会工作。
有什么替代方案可以适用于我的情况吗?
首先,我建议创建一个捕获抽象数据类型语义的自定义类型。这样您就可以尝试不同的实现,这样您的呼叫站点就可以自我记录。
internal sealed class NameCounter
{
public int GetCount(string Name) { ... }
public void Increment(string Name) { ... }
}
那么:鉴于这必须是线程安全的,你可以做出哪些实现选择?
Dictionary<string, int>
可以工作,但你必须在每次访问时锁定字典,这可能会变得昂贵。ConcurrentDictionary<string, int>
,但请记住,你必须在循环中使用TryUpdate
,以确保你不会失去价值。internal sealed class MutableInt
{
public int Value;
}
这是您想要建立公共领域的罕见情况之一。现在做一个ConcurrentDictionary<string, MutableInt>
,然后InterlockedIncrement
公共领域。现在你没有TryUpdate
,但这里仍有一场比赛:如果两个线程都是第一次尝试同时添加相同的名字,那么你必须确保其中只有一个获胜。小心使用AddOrUpdate
以确保不会发生这场比赛。
InterlockedIncrement
关于数组的元素。同样,在向系统引入新名称时,您必须非常小心,以确保以线程安全的方式检测到哈希冲突。