[原创][6]探究C#多线程开发细节-“ConcurrentDictionary<T,T>解决多线程的无顺序性的问题“

news2025/1/17 21:37:30

[简介]
常用网名: 猪头三
出生日期: 1981.XX.XX
QQ联系: 643439947
个人网站: 80x86汇编小站 https://www.x86asm.org
编程生涯: 2001年~至今[共22年]
职业生涯: 20年
开发语言: C/C++、80x86ASM、PHP、Perl、Objective-C、Object Pascal、C#、Python
开发工具: Visual Studio、Delphi、XCode、Eclipse、C++ Builder
技能种类: 逆向 驱动 磁盘 文件
研发领域: Windows应用软件安全/Windows系统内核安全/Windows系统磁盘数据安全/macOS应用软件安全
项目经历: 磁盘性能优化/文件系统数据恢复/文件信息采集/敏感文件监测跟踪/网络安全检测

[序言]
上一篇"[原创][5]探究C#多线程开发细节-利用AutoResetEvent类解决多线程循环轮询假同步的问题.-CSDN博客"文章结尾提到过, 可以用ConcurrentDictionary<T,T>代替ConcurrentQueue<T> 管理AutoResetEvent事件会更加方便. 为什么会方便呢? 第一: 省去了ConcurrentQueue<T>的ToArray()转换问题. 第二: 通过ConcurrentDictionary<T,T>的TKey去查找目标线程的对应AutoResetEvent事件会更加方便, 代码可读性更强.

[下面是完整的代码]
为了更能直观地表显示出多线程的交互关系, 我扩展了更多的信息在界面上显示而且还配上了截图, 大家可以一边阅读源码, 一边观看下方的GIF图片, 慢慢领悟多线程的核心逻辑.

        private ConcurrentDictionary<int, AutoResetEvent> mpr_cdic_ThreadEvent = new ConcurrentDictionary<int, AutoResetEvent>();

        public class Thread_Run
        {
            public int mpu_int_ThreadIndex;
            private Action<int> mpr_action_UpdateWaitInfo;
            private Action<int> mpr_action_UpdateRunInfo;
            private ConcurrentDictionary<int, AutoResetEvent> mpr_cdic_ThreadEvent;
            private AutoResetEvent mpr_event_State;

            public Thread_Run(Action<int> action_param_UpdateWaitInfo,
                              Action<int> action_param_UpdateRunInfo,
                              ref ConcurrentDictionary<int, AutoResetEvent> cdic_param_ThreadEvent,
                              object obj_param_EventState)
            {
                mpr_action_UpdateWaitInfo = action_param_UpdateWaitInfo;
                mpr_action_UpdateRunInfo = action_param_UpdateRunInfo;
                mpr_cdic_ThreadEvent = cdic_param_ThreadEvent;
                mpr_event_State = (AutoResetEvent)obj_param_EventState;
            }

            public int mpu_fun_ShowIndex()
            {
                return mpu_int_ThreadIndex;
            }

            public void mpu_pro_StartThread()
            {
                
                Thread class_Thread = new Thread(Thread_Exe);
                class_Thread.Start();
            }

            private void Thread_Exe()
            {

                // 模拟工作
                Random class_Random = new Random();
                Thread.Sleep(class_Random.Next(1, 11)*1000);

                if (mpu_int_ThreadIndex != 0)
                {
                    //调用委托方法来更新UI
                    mpr_action_UpdateRunInfo?.Invoke(mpu_int_ThreadIndex);

                    // 如果不是第一个线程则直接等待
                    mpr_event_State.WaitOne();
                }

                //调用委托方法来更新UI
                mpr_action_UpdateWaitInfo?.Invoke(mpu_int_ThreadIndex);

                // 通知当前线程的下一个线程放弃等待,可直接返回
                // 比如当前是1号线程,那么它的下一个就是2号线程
                AutoResetEvent event_Next;
                if (mpr_cdic_ThreadEvent.TryGetValue(mpu_int_ThreadIndex + 1, out event_Next))
                {
                    event_Next.Set();
                }

            }

        }// End Thread_Run()

        public Form_Main()
        {
            InitializeComponent();
        }

        public void mpu_pro_UpdateWaiteInfo(int int_param_ThreadIndex)
        {

            if (InvokeRequired)
            {
                this.Invoke((MethodInvoker)delegate {

                    lb_WaitInfo.Text += (Environment.NewLine + string.Format("{0} 号线程已正常退出.", int_param_ThreadIndex));

                });
            }
        }

        public void mpu_pro_UpdateRunInfo(int int_param_ThreadIndex)
        {

            if (InvokeRequired)
            {
                this.Invoke((MethodInvoker)delegate {

                    lb_RunInfo.Text += (Environment.NewLine + string.Format("{0} 号线程已完成工作, 正等待 {1} 号线程退出...", int_param_ThreadIndex, int_param_ThreadIndex-1));

                });
            }
        }

        private void Bn_StartThread_Click(object sender, EventArgs e)
        {

            // 启动10个线程
            for (int int_Index = 0; int_Index < 10; int_Index++)
            {

                var var_ThreadEvent = new AutoResetEvent(false);
                mpr_cdic_ThreadEvent.TryAdd(int_Index, var_ThreadEvent);
                Thread_Run class_ThreadRun = new Thread_Run(mpu_pro_UpdateWaiteInfo, mpu_pro_UpdateRunInfo, ref mpr_cdic_ThreadEvent, var_ThreadEvent);
                class_ThreadRun.mpu_int_ThreadIndex = int_Index;
                class_ThreadRun.mpu_pro_StartThread();
                
            }

        }

    }

[截图欣赏]
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1293915.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

电商系统架构演进

聊聊电商系统架构演进 具体以电子商务网站为例&#xff0c; 展示web应用的架构演变过程。 1.0时代 这个时候是一个web项目里包含了所有的模块&#xff0c;一个数据库里包含了所需要的所有表&#xff0c;这时候网站访问量增加时&#xff0c;首先遇到瓶颈的是应用服务器连接数&a…

【动态规划】03使用最小花费爬楼梯(easy1)

题目链接&#xff1a;leetcode使用最小花费爬楼梯 目录 题目解析&#xff1a; 算法原理 1.状态表示 2.状态转移方程 3.初始化 4.填表顺序 5.返回值 编写代码 题目解析&#xff1a; 题目让我们求达到楼梯顶部的最低花费. 由题可得&#xff1a; cost[i] 是从楼梯第 i 个…

AI并行计算:CUDA和ROCm

1 介绍 1.1 CUDA CUDA&#xff08;Compute Unified Device Architecture&#xff09;是Nvidia于2006年推出的一套通用并行计算架构&#xff0c;旨在解决在GPU上的并行计算问题。其易用性和便捷性能够方便开发者方便的进行GPU编程&#xff0c;充分利用GPU的并行能力&#xff0…

利用管道、信号量、信号、共享内存和消息队列进行多进程通信

一.管道&#xff08;分为命名管道和匿名管道&#xff09; 管道的特点&#xff1a; ①无论是命名管道还是匿名管道&#xff0c;写入管道的数据都存放在内存之中。 ②管道是一种半双工的通信方式&#xff08;半双工是指终端A能发信号给终端B&#xff0c;终端B也能发信号给终端…

ISIS默认路由下发的各种机制

作者简介&#xff1a;大家好&#xff0c;我是Asshebaby&#xff0c;热爱网工&#xff0c;有网络方面不懂的可以加我一起探讨 :1125069544 个人主页&#xff1a;Asshebaby博客 当前专栏&#xff1a; 网络HCIP内容 特色专栏&#xff1a; 常见的项目配置 本文内容&am…

VC++使用GetProcessTimes获取进程创建时间、销毁时间、用户态时间、内核态时间

一、GetProcessTimes函数简介&#xff08;微软MSDN&#xff09; 微软提供了一个非常有用的API函数GetProcessTimes用来获取进程创建时间、销毁时间、用户态时间、内核态时间&#xff0c;msdn连接为&#xff1a;GetProcessTimes 函数 (processthreadsapi.h) 其函数原型为&#…

网络管理相关

管理功能分为管理站manager和代理agent两部分。 网络管理&#xff1a; 网络管理系统中&#xff0c;每一个网络节点都包含有一组与管理有关的软件&#xff0c;叫做网络管理实体NME。 管理站的另外一组软件叫做网络管理应用NMA&#xff0c;提供用户接口&#xff0c;根据用户命令显…

渗透测试(Lab1.0)

1、用搜索引擎Google或百度搜索麻省理工学院网站中文件名包含“network security”的pdf文档&#xff0c;截图搜索得到的页面。 2、照片中的女生在哪里旅行&#xff1f; 截图搜索到的地址信息。 搜索餐厅的名字&#xff0c;找一下关键词 3、手机位置定位 通过LAC&#xff0…

【Ambari】Python调用Rest API 获取YARN HA状态信息并发送钉钉告警

&#x1f984; 个人主页——&#x1f390;开着拖拉机回家_Linux,大数据运维-CSDN博客 &#x1f390;✨&#x1f341; &#x1fa81;&#x1f341;&#x1fa81;&#x1f341;&#x1fa81;&#x1f341;&#x1fa81;&#x1f341; &#x1fa81;&#x1f341;&#x1fa81;&am…

Javascript 函数介绍

Javascript 函数介绍 很多教程书一上来就讲解一堆语法&#xff0c;例如函数定义、函数调用什么。等读者看完了函数这一章都没搞懂什么是函数。 在讲解什么叫函数之前&#xff0c;我们先看下面一段代码&#xff1a; <!DOCTYPE html> <html xmlns"http://www.w3.…

介绍java spring 提供的默认数据库持久化技术 JdbcTemplate基本演示

之前 我们说过spring贴心的内嵌了三种数据源形式 其中默认为HikariCP 其实 spring 也提供了持久化数据库连接技术 这个技术其实大部分都接触过 那就是 JDBC 随着时代的发展 用他的人也越来越少了 那么 我们要演示 JdbcTemplate 导入 mybatis 或 mybatis-plus 的片段 就要注掉了…

nacos服务的分级存储

举例说明 一个服务可以有多个实例&#xff0c;比如我们当前有4个实例&#xff0c;都叫做nacos-user-service服务 ip地址端口服务器所属地区集群192.168.xxx.xxx18080广东GD192.168.xxx.xxx18081广东GD192.168.xxx.xxx18082广西GX192.168.xxx.xxx18083广西GX所以我们可以将nacos…

跨境电商独立站怎么获取流量 跨境电商引流的两个方法

独立站有着比SaaS和中心化站点不一样的特点&#xff0c;今天介绍两种引流的主要玩法&#xff1a; 独立站的第一种玩法是通过数据&#xff0c;找到爆款&#xff0c;搭建独立站&#xff0c;企业站加电商功能、交易、订单配送功能&#xff0c;搜索引擎seo引流法&#xff0c;外联渠…

服务器RAID系统的常见故障,结合应用场景谈谈常规的维修处理流程

常见的服务器RAID系统故障包括硬盘故障、控制器故障、电源故障、写入错误和热插拔错误。下面结合这些故障的应用场景和常规维修处理流程来详细讨论&#xff1a; 硬盘故障&#xff1a; 应用场景&#xff1a;在服务器RAID系统中&#xff0c;硬盘故障是最常见的问题之一。硬盘可能…

[MySQL--基础]事务的基础知识

前言 ⭐Hello!这里是欧_aita的博客。 ⭐今日语录&#xff1a;生活中最重要的决定就是要做出决定。 ⭐个人主页&#xff1a;欧_aita ψ(._. )>⭐个人专栏&#xff1a; 数据结构与算法 MySQL数据库 事务的目录&#x1f4d5; 前言事务简介&#x1f680;事务操作&#x1f680;准…

【头歌系统Python实验】顺序与选择结构

目录 第1关&#xff1a;顺序结构 第2关&#xff1a;选择结构&#xff1a;if-else 第3关&#xff1a;选择结构 &#xff1a; 三元操作符 如果对你有帮助的话&#xff0c;不妨点赞收藏评论一下吧&#xff0c;爱你么么哒&#x1f618;❤️❤️❤️ 第1关&#xff1a;顺序结构 …

批量AI写作生成器有哪些?免费的批量AI写作生成器

当今信息爆炸的时代&#xff0c;文案需求量庞大&#xff0c;传统文案写作已无法满足快速迭代的需求。批量AI写作生成器应运而生&#xff0c;成为许多行业的得力助手。在众多AI写作工具中&#xff0c;147原创助手以其批量AI写作功能和在各大平台显示原创首发的特性脱颖而出。本文…

大数据项目——基于Django/协同过滤算法的房源可视化分析推荐系统的设计与实现

大数据项目——基于Django/协同过滤算法的房源可视化分析推荐系统的设计与实现 技术栈&#xff1a;大数据爬虫/机器学习学习算法/数据分析与挖掘/大数据可视化/Django框架/Mysql数据库 本项目基于 Django框架开发的房屋可视化分析推荐系统。这个系统结合了大数据爬虫、机器学…

redis-学习笔记(hash)

Redis 自身已经是 键值对 结构了 Redis 自身的键值对就是通过 哈希 的方式来组织的 把 key 这一层组织完成后, 到了 value 这一层, 还可以用 哈希类型 来组织 (简单的说就是哈希里面套哈希 [数组里面套数组 -> 二维数组] ) [ field value ] hset key field value [ field va…

C++刷题 -- 链表

C刷题 – 链表 文章目录 C刷题 -- 链表1.删除链表的倒数第 N 个结点2.链表相交3.环形链表 1.删除链表的倒数第 N 个结点 https://leetcode.cn/problems/remove-nth-node-from-end-of-list/ 快慢指针的应用 fast指针先移动N步&#xff0c;slow依然指向head&#xff1b;然后fa…