您的位置:首页 >高并发下C#安全操作静态字典方法
发布于2026-01-17 阅读(0)
扫一扫,手机访问
应使用ConcurrentDictionary<T>替代static Dictionary<K,V>,因其采用分段锁与CAS保证线程安全;静态List<T>则优先选用ConcurrentQueue<T>或ConcurrentBag<T>,避免手动加锁引发死锁或性能问题。

static Dictionary<K, V> 会出问题因为 Dictionary<K, V> 和 List<T> 都不是线程安全的。高并发下多个线程同时调用 Add、Remove 或遍历,可能触发 InvalidOperationException(“集合已修改”),甚至出现数据丢失、索引越界或内存损坏——这不是偶发 bug,而是确定性崩溃。
ConcurrentDictionary<K, V> 替代静态 Dictionary这是最直接的替换方案,它内部用分段锁 + CAS 操作保证读写安全,且读操作无锁,性能远好于全局 lock。
GetOrAdd(key, factory) 是原子的,适合缓存场景,避免重复初始化AddOrUpdate(key, addValueFactory, updateValueFactory) 可安全处理“有则更新、无则添加”逻辑foreach 是安全的,但迭代器看到的是快照,不反映实时增删Keys 或 Values 属性后直接遍历——它们返回的是只读集合,但底层仍可能被其他线程修改,建议先转成数组:var keys = dict.Keys.ToArray();
List<T> 的安全替代:优先用 ConcurrentQueue<T> 或 ConcurrentBag<T>如果只是追加+消费(如日志缓冲、任务队列),别硬扛 List<T> + lock。静态 List<T> 几乎没有安全又高效的并发使用方式。
ConcurrentQueue<T>:FIFO,Enqueue/TryDequeue 全部线程安全,无锁实现,适合生产者-消费者模型ConcurrentBag<T>:无序,对“同一线程频繁 Add/Remove”做了本地缓存优化,适合短期对象池场景ImmutableList<T> + 原子更新:list = list.Add(item); // 返回新实例,旧引用不变但注意内存开销和 GC 压力
lock 时,必须避开常见陷阱静态锁对象必须是私有、只读、不可变的,且不能是 typeof(MyClass) 或字符串字面量——它们可能被外部代码锁定,引发死锁或锁竞争放大。
private static readonly object _lockObj = new object();
lock,只锁真正共享修改的几行ConcurrentDictionary 和 ConcurrentQueue 已覆盖绝大多数场景;手动加锁是最后手段,且一旦引入,就必须严格控制锁对象生命周期和临界区范围。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
9