在C#多线程开发中,如果多个线程同时读写同一个Dictionary实例,很容易抛出InvalidOperationException或者产生数据不一致。ConcurrentDictionary位于System.Collections.Concurrent命名空间,是专为高并发场景设计的线程安全字典,内部通过分段锁等机制减少阻塞。

基本初始化与添加
使用ConcurrentDictionary时,最常见的操作是线程安全地添加元素。相比Dictionary的Add方法,它提供了TryAdd来避免重复键异常。
using System;
using System.Collections.Concurrent;
class Program
{
static void Main()
{
ConcurrentDictionary<string, int> dict = new ConcurrentDictionary<string, int>();
bool added = dict.TryAdd("apple", 1);
Console.WriteLine(added); // True
added = dict.TryAdd("apple", 2);
Console.WriteLine(added); // False,键已存在
}
}
获取或添加
当我们需要缓存数据时,经常需要“如果不存在就添加,存在就返回”的原子操作,这时可以使用GetOrAdd。
using System;
using System.Collections.Concurrent;
class Program
{
static void Main()
{
ConcurrentDictionary<string, int> dict = new ConcurrentDictionary<string, int>();
int value = dict.GetOrAdd("count", 100);
Console.WriteLine(value); // 100
value = dict.GetOrAdd("count", 200);
Console.WriteLine(value); // 100,不会覆盖
}
}
更新已存在的键
AddOrUpdate允许我们根据旧值计算新值,在计数器场景中非常实用。
using System;
using System.Collections.Concurrent;
class Program
{
static void Main()
{
ConcurrentDictionary<string, int> dict = new ConcurrentDictionary<string, int>();
dict.TryAdd("hit", 0);
int result = dict.AddOrUpdate("hit", 1, (key, old) => old + 1);
Console.WriteLine(result); // 1
result = dict.AddOrUpdate("hit", 1, (key, old) => old + 1);
Console.WriteLine(result); // 2
}
}
删除与遍历
ConcurrentDictionary同样支持TryRemove,并且在遍历时不会因其他线程修改而抛异常。
using System;
using System.Collections.Concurrent;
class Program
{
static void Main()
{
ConcurrentDictionary<string, int> dict = new ConcurrentDictionary<string, int>();
dict.TryAdd("a", 1);
dict.TryAdd("b", 2);
if (dict.TryRemove("a", out int removed))
{
Console.WriteLine(removed);
}
foreach (var item in dict)
{
Console.WriteLine(item.Key + ":" + item.Value);
}
}
}
方法对比
| 方法 | 作用 | 是否原子 |
|---|---|---|
| TryAdd | 键不存在时添加 | 是 |
| GetOrAdd | 获取或添加默认值 | 是 |
| AddOrUpdate | 更新已有键值 | 是 |
| TryRemove | 移除指定键 | 是 |
在多数业务代码中,优先使用上述原子方法,可以减少手动lock带来的死锁风险和性能损耗。如果操作非常复杂且必须多步完成,再考虑使用传统锁方案。
C#ConcurrentDictionary线程安全修改时间:2026-07-31 06:21:09