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

如何解决C#字典的线程安全问题

前言

我们在上位机软件开发过程中经常需要使用字典这个数据结构,并且经常会在多线程环境中使用字典,如果使用常规的Dictionary就会出现各种异常,本文就是详细介绍如何在多线程环境中使用字典来解决线程安全问题。

1、非线程安全举例

Dictionary<int, int> dic = new Dictionary<int, int>();private void TestAddNotSafe1(){while (true){for (int i = 0; i < 1000000; i++){if (dic.ContainsKey(i) == false){dic.Add(i, i);}Thread.Sleep(1);}break;}}private void TestAddNotSafe2(){while (true){for (int i = 0; i < 1000000; i++){if (dic.ContainsKey(i) == false){dic.Add(i, i);}Thread.Sleep(1);}break;}}
 Task.Run(TestAddNotSafe1);Task.Run(TestAddNotSafe2);

上述代码运行后报错,如下:
这是当前线程判断没有该键,准备添加键值对的时候,另一个线程已经添加了该键,所以提示已经添加了相同的项。
在这里插入图片描述

2、线程安全举例

为了解决上面的问题,需要使用一个线程安全的字典,

ConcurrentDictionary<int, int> concurrentDictionary = new ConcurrentDictionary<int, int>();private void TestAddSafe1(){while (true){for (int i = 0; i < 1000000; i++){if (concurrentDictionary.ContainsKey(i) == false){if (concurrentDictionary.TryAdd(i, i)){}else{MessageBox.Show("错误1");}}Thread.Sleep(1);}break;}}private void TestAddSafe2(){while (true){for (int i = 0; i < 1000000; i++){if (concurrentDictionary.ContainsKey(i) == false){if (concurrentDictionary.TryAdd(i, i)){}else{MessageBox.Show("错误2");}}Thread.Sleep(1);}break;}}
   Task.Run(TestAddSafe1);Task.Run(TestAddSafe2);

运行后弹出窗体,提示“错误1”或者“错误2”,但是软件没有崩溃,这是因为TryAdd方法调用返回了false,所以线程安全字典的好处是不会导致软件崩溃,添加值失败只会返回false而已。
在这里插入图片描述

总结:

对于字典的线程安全问题,除了TryAdd方法外还有TryRemove、TryUpdate方法。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 40.组合综合Ⅱ
  • 【JavaEE精炼宝库】 网络编程套接字——UDP业务逻辑 | TCP流套接字编程及业务逻辑实现
  • 沉浸式企业VR展厅,重塑企业形象展示方式!
  • 程序员进阶架构知识体系、开发运维工具使用、Java体系知识扩展、前后端分离流程详解、设计模式开发实例汇总专栏分享
  • ComfyUI: 报EP Error错误(onnxruntime)
  • nginx的反向代理及负载均衡
  • 软件测试基础1--功能测试
  • EasyAR_稠密空间图
  • RIP综合练习
  • 在快速消费品业务中利用知识管理的指南
  • 文件存储服务系统(File Storage Service System)-02-SFTP 协议介绍
  • 【从零开始一步步学习VSOA开发】开发环境搭建
  • 谷粒商城实战笔记-110~114-全文检索-ElasticSearch-查询
  • CTFSHOW 萌新 web10 解题思路和方法(passthru执行命令)
  • 如何获取和安装SSL证书
  • 【面试系列】之二:关于js原型
  • 10个最佳ES6特性 ES7与ES8的特性
  • AzureCon上微软宣布了哪些容器相关的重磅消息
  • echarts的各种常用效果展示
  • hadoop集群管理系统搭建规划说明
  • iOS动画编程-View动画[ 1 ] 基础View动画
  • JAVA并发编程--1.基础概念
  • JS字符串转数字方法总结
  • oldjun 检测网站的经验
  • SOFAMosn配置模型
  • SSH 免密登录
  • ⭐ Unity 开发bug —— 打包后shader失效或者bug (我这里用Shader做两张图片的合并发现了问题)
  • 闭包--闭包作用之保存(一)
  • 开源SQL-on-Hadoop系统一览
  • 微服务核心架构梳理
  • 源码安装memcached和php memcache扩展
  • 栈实现走出迷宫(C++)
  • kubernetes资源对象--ingress
  • 函数计算新功能-----支持C#函数
  • ​​​​​​​开发面试“八股文”:助力还是阻力?
  • ​​快速排序(四)——挖坑法,前后指针法与非递归
  • ​Z时代时尚SUV新宠:起亚赛图斯值不值得年轻人买?
  • ​数据链路层——流量控制可靠传输机制 ​
  • # centos7下FFmpeg环境部署记录
  • #QT(智能家居界面-界面切换)
  • (2020)Java后端开发----(面试题和笔试题)
  • (M)unity2D敌人的创建、人物属性设置,遇敌掉血
  • (黑马出品_高级篇_01)SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式
  • (每日持续更新)jdk api之FileFilter基础、应用、实战
  • (切换多语言)vantUI+vue-i18n进行国际化配置及新增没有的语言包
  • (一)为什么要选择C++
  • (原創) 如何使用ISO C++讀寫BMP圖檔? (C/C++) (Image Processing)
  • (转载)VS2010/MFC编程入门之三十四(菜单:VS2010菜单资源详解)
  • (总结)Linux下的暴力密码在线破解工具Hydra详解
  • ./mysql.server: 没有那个文件或目录_Linux下安装MySQL出现“ls: /var/lib/mysql/*.pid: 没有那个文件或目录”...
  • .360、.halo勒索病毒的最新威胁:如何恢复您的数据?
  • .bat批处理(十一):替换字符串中包含百分号%的子串
  • .libPaths()设置包加载目录
  • .Net Core/.Net6/.Net8 ,启动配置/Program.cs 配置
  • .Net Memory Profiler的使用举例