c# 如何在高并发下安全地操作静态字典或列表
发布时间 - 2026-01-09 00:00:00 点击率:次应使用ConcurrentDictionary替代static Dictionary,因其采用分段锁与CAS保证线程安全;静态List则优先选用ConcurrentQueue或ConcurrentBag,避免手动加锁引发死锁或性能问题。
为什么直接用 static Dictionary 会出问题
因为 Dictionary 和 List 都不是线程安全的。高并发下多个线程同时调用 Add、Remove 或遍历,可能触发 InvalidOperationException(“集合已修改”),甚至出现数据丢失、索引越界或内存损坏——这不是偶发 bug,而是确定性崩溃。
用 ConcurrentDictionary 替代静态 Dictionary
这是最直接的替换方案,它内部用分段锁 + CAS 操作保证读写安全,且读操作无锁,性能远好于全局 lock。
-
GetOrAdd(key, factory)是原子的,适合缓存场景,避免重复初始化 -
AddOrUpdate(key, addValueFactory, updateValueFactory)可安全处理“有则更新、无则添加”逻辑 - 遍历时用
foreach是安全的,但迭代器看到的是快照,不反映实时增删 - 避免用
Keys或Values属性后直接遍历——它们返回的是只读集合,但底层仍可能被其他线程修改,建议先转成数组:var keys = dict.Keys.ToArray();
静态 List 的安全替代:优先用 ConcurrentQueue 或 ConcurrentBag
如果只是追加+消费(如日志缓冲、任务队列),别硬扛 List + lock。静态 List 几乎没有安全又高效的并发使用方式。
-
ConcurrentQueue:FIFO,Enqueue/TryDequeue全部线程安全,无锁实现,适合生产者-消费者模型 -
ConcurrentBag:无序,对“同一线程频繁 Add/Remove”做了本地缓存优化,适合短期对象池场景 - 真需要随机访问索引?考虑
ImmutableList+ 原子更新:list = list.Add(item); // 返回新实例,旧引用不变
但注意内存开销和 GC 压力
万不得已用 lock 时,必须避开常见陷阱
静态锁对象必须是私有、只读、不可变的,且不能是 typeof(MyClas 或字符串字面量——它们可能被外部代码锁定,引发死锁或锁竞争放大。
s)
- 正确写法:
private static readonly object _lockObj = new object();
- 锁粒度要细:不要把整个方法体包进
lock,只锁真正共享修改的几行 - 禁止在锁内调用未知外部代码(如事件、虚方法、LINQ 查询),可能反向调用本类导致死锁
- 避免嵌套锁:同一上下文多次获取同一锁对象不会死锁,但若涉及多个锁,顺序不一致就极易死锁
ConcurrentDictionary 和 ConcurrentQueue 已覆盖绝大多数场景;手动加锁是最后手段,且一旦引入,就必须严格控制锁对象生命周期和临界区范围。
# c#
# 数据丢失
# 无锁
# 为什么
# Static
# foreach
# 字符串
# 线程
# 并发
# 对象
# 事件
# typeof
# linq
# bug
# 死锁
# 遍历
# 的是
# 多个
# 加锁
# 这是
# 本类
# 要把
# 这不是
# 而非
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Laravel如何发送邮件和通知_Laravel邮件与通知系统发送步骤
Win11怎么修改DNS服务器 Win11设置DNS加速网络【指南】
如何在阿里云通过域名搭建网站?
阿里云网站搭建费用解析:服务器价格与建站成本优化指南
logo在线制作免费网站在线制作好吗,DW网页制作时,如何在网页标题前加上logo?
Laravel如何清理系统缓存命令_Laravel清除路由配置及视图缓存的方法【总结】
ChatGPT怎么生成Excel公式_ChatGPT公式生成方法【指南】
简历没回改:利用AI润色让你的文字更专业
JS实现鼠标移上去显示图片或微信二维码
Laravel如何实现用户密码重置功能?(完整流程代码)
laravel怎么配置Redis作为缓存驱动_laravel Redis缓存配置教程
jquery插件bootstrapValidator表单验证详解
ai格式如何转html_将AI设计稿转换为HTML页面流程【页面】
北京专业网站制作设计师招聘,北京白云观官方网站?
百度输入法ai面板怎么关 百度输入法ai面板隐藏技巧
独立制作一个网站多少钱,建立网站需要花多少钱?
如何快速搭建高效简练网站?
如何快速搭建高效WAP手机网站吸引移动用户?
laravel怎么用DB facade执行原生SQL查询_laravel DB facade原生SQL执行方法
品牌网站制作公司有哪些,买正品品牌一般去哪个网站买?
网站页面设计需要考虑到这些问题
javascript中的数组方法有哪些_如何利用数组方法简化数据处理
矢量图网站制作软件,用千图网的一张矢量图做公司app首页,该网站并未说明版权等问题,这样做算不算侵权?应该如何解决?
Android自定义控件实现温度旋转按钮效果
如何破解联通资金短缺导致的基站建设难题?
微信小程序制作网站有哪些,微信小程序需要做网站吗?
Laravel怎么实现微信登录_Laravel Socialite第三方登录集成
如何正确选择百度移动适配建站域名?
Laravel Seeder怎么填充数据_Laravel数据库填充器的使用方法与技巧
php打包exe后无法访问网络共享_共享权限设置方法【教程】
如何在香港免费服务器上快速搭建网站?
php后缀怎么变mp4格式错误_修改扩展名提示格式不对怎么办【技巧】
laravel怎么为API路由添加签名中间件保护_laravel API路由签名中间件保护方法
高防服务器:AI智能防御DDoS攻击与数据安全保障
php中::能调用final静态方法吗_final修饰静态方法调用规则【解答】
Win11任务栏卡死怎么办 Windows11任务栏无反应解决方法【教程】
Chrome浏览器标签页分组怎么用_谷歌浏览器整理标签页技巧【效率】
宙斯浏览器视频悬浮窗怎么开启 边看视频边操作其他应用教程
php json中文编码为null的解决办法
Android Socket接口实现即时通讯实例代码
大连网站制作费用,大连新青年网站,五年四班里的视频怎样下载啊?
Laravel的Blade指令怎么自定义_创建你自己的Laravel Blade Directives
如何快速搭建高效服务器建站系统?
如何在宝塔面板中修改默认建站目录?
如何在阿里云购买域名并搭建网站?
Win11怎样安装网易有道词典_Win11安装词典教程【步骤】
Laravel中的withCount方法怎么高效统计关联模型数量
php嵌入式断网后怎么恢复_php检测网络重连并恢复硬件控制【操作】
如何在Windows 2008云服务器安全搭建网站?
Laravel怎么进行数据库事务处理_Laravel DB Facade事务操作确保数据一致性

