当前位置: 首页 > news >正文

ConcurrentDictionary 详解:.NET 中的线程安全字典

什么是 ConcurrentDictionary?

ConcurrentDictionary<TKey, TValue> 是 .NET Framework 4.0+ 和 .NET Core/.NET 5+ 中引入的线程安全字典实现,位于 System.Collections.Concurrent 命名空间。它解决了多线程环境下操作字典时的同步问题,允许**多个线程同时读写字典**而无需显式加锁。

核心特性

  1. 线程安全:所有操作都是原子性的
  2. 高性能:使用细粒度锁(而非全局锁)
  3. 无锁读取:读操作通常不需要锁
  4. 原子方法:提供专门设计的线程安全方法

与普通 Dictionary 的对比

特性DictionaryConcurrentDictionary
线程安全❌ 需要手动加锁✅ 内置线程安全
读性能非常高(无锁读取)
写性能较高(细粒度锁)
并发支持需要同步机制原生支持并发
内存开销较低稍高(维护内部结构)

基本使用

// 创建实例
var concurrentDict = new ConcurrentDictionary<string, int>();// 添加元素(线程安全)
concurrentDict.TryAdd("task1", 0);
concurrentDict.TryAdd("task2", 0);// 更新元素(原子操作)
concurrentDict.AddOrUpdate("task1", key => 1,               // 添加时的工厂函数(key, oldValue) => oldValue + 1 // 更新时的函数
);// 安全获取值
if (concurrentDict.TryGetValue("task1", out int value))
{Console.WriteLine($"Task1 进度: {value}%");
}// 删除元素
concurrentDict.TryRemove("task2", out _);

关键方法详解

1. TryAdd()
bool success = concurrentDict.TryAdd("task3", 25);
// 成功添加返回 true,键已存在返回 false
2. TryUpdate()
int currentValue;
do {currentValue = concurrentDict["task1"];
} while (!concurrentDict.TryUpdate("task1", currentValue + 10, currentValue));
// 原子性更新:只有当前值等于 expectedValue 时才更新
3. AddOrUpdate()
// 添加或更新(原子操作)
int newValue = concurrentDict.AddOrUpdate("task1", key => 50,                // 添加时的工厂函数(key, oldValue) => oldValue + 10 // 更新时的函数
);
4. GetOrAdd()
// 获取或添加(原子操作)
int value = concurrentDict.GetOrAdd("task4", key => 0);
// 如果 task4 不存在,初始化为 0
5. TryRemove()
if (concurrentDict.TryRemove("task2", out int removedValue))
{Console.WriteLine($"已删除 task2,原值: {removedValue}");
}

在任务进度系统中的应用

进度存储服务实现
public class ConcurrentTaskProgressService
{private readonly ConcurrentDictionary<string, TaskProgress> _progressStore = new ConcurrentDictionary<string, TaskProgress>();public void UpdateProgress(string taskId, int completed, int total){_progressStore.AddOrUpdate(taskId,// 添加新任务id => new TaskProgress{TaskId = id,Completed = completed,Total = total,LastUpdated = DateTime.UtcNow},// 更新现有任务(id, existing) =>{existing.Completed = completed;existing.Total = total;existing.LastUpdated = DateTime.UtcNow;return existing;});}public TaskProgress GetProgress(string taskId){return _progressStore.TryGetValue(taskId, out var progress) ? progress : null;}
}public class TaskProgress
{public string TaskId { get; set; }public int Completed { get; set; }public int Total { get; set; }public DateTime LastUpdated { get; set; }public int Percentage => Total > 0 ? (Completed * 100) / Total : 0;
}

最佳实践

  1. 优先使用原子方法

    // ✅ 推荐
    dict.AddOrUpdate(key, 1, (k, v) => v + 1);// ❌ 避免(非原子操作)
    if (dict.ContainsKey(key)) {dict[key] = dict[key] + 1;
    }
    
  2. 处理工厂函数副作用

    // 工厂函数应简单无副作用
    var value = dict.GetOrAdd(key, k => {// 避免耗时操作return CalculateInitialValue(k);
    });
    
  3. 迭代时处理并发修改

    foreach (var pair in concurrentDict)
    {// 注意:迭代期间字典可能被修改Process(pair.Value);
    }
    
  4. 值类型注意事项

    // 值类型更新需特殊处理
    var dict = new ConcurrentDictionary<string, (int, DateTime)>();dict.AddOrUpdate("task", k => (0, DateTime.UtcNow),(k, v) => (v.Item1 + 1, DateTime.UtcNow)
    );
    

性能考量

  1. 读取密集型场景:性能接近无锁读取
  2. 写入密集型场景:比锁+Dictionary 性能高 2-3 倍
  3. 混合工作负载:在高并发下表现最佳

使用场景

  1. 缓存系统
  2. 实时监控/统计
  3. 并行计算中间结果
  4. 高并发计数器
  5. 任务调度系统(如所述进度监控)

总结

ConcurrentDictionary 是 .NET 中处理并发字典操作的首选方案,它:

  • 提供线程安全的原子操作
  • 比手动锁实现更高效
  • 简化多线程编程模型
  • 特别适合高频读写的场景

在任务进度监控系统中,使用 ConcurrentDictionary 可以安全高效地管理多个任务的进度状态,确保在高并发环境下数据的一致性和实时性。

http://www.xdnf.cn/news/1260199.html

相关文章:

  • simulink tlc如何通过tlc写数据入文件
  • Spring Boot + Angular 实现安全登录注册系统:全栈开发指南
  • 深入理解 Java AWT Container:原理、实战与性能优化
  • 使用Prometheus + Grafana + node_exporter实现Linux服务器性能监控
  • 【3d61638 渍韵】001 png pdf odt 5与明天各种号(虚拟文章スミレ数据)
  • 从零开始构建【顺序表】:C语言实现与项目实战准备
  • 【前端】纯代码实现Power BI自动化
  • 破界之光:DeepSeek 如何重构AI搜索引擎的文明坐标 || #AIcoding·八月创作之星挑战赛#
  • 点播服务器
  • Day10 SpringAOP
  • Linux 学习 ------Linux 入门(上)
  • DuoPlus支持导入文件批量配置云手机参数,还优化了批量操作和搜索功能!
  • DigitalProductId解密算法php版
  • 三种经典寻路算法对比
  • 在 Mac 上安装 IntelliJ IDEA
  • 2025产品经理接单经验分享与平台汇总
  • 2025最新版天猫图片搜索API全解析:从图像识别到商品匹配实战
  • TensorFlow深度学习实战(29)——自监督学习(Self-Supervised Learning)
  • 存储管理、XFS 增量备份恢复、LVM
  • 【Qt开发】常用控件(二) -> enabled
  • GoLand 项目从 0 到 1:第六天 —— 权限接口开发与问题攻坚
  • npm run 常见脚本
  • HarmonyOS SDK助力讯飞听见App能力建设
  • Java技术栈/面试题合集(21)-Docker篇
  • 仅需8W,无人机巡检系统落地 AI 低空智慧城市!可源码交付
  • ADB打印设备日志相关
  • WWDC 25 玻璃态星际联盟:SwiftUI 视图协同“防御协议”
  • 深入理解 robots.txt:网站与搜索引擎的 “沟通协议”
  • Linux文档压缩打包与安装
  • zookeeper3.8.4安装以及客户端C++api编译