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

本文主要是介绍[原创][6]探究C#多线程开发细节-“ConcurrentDictionary<T,T>解决多线程的无顺序性的问题“,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

[简介]
常用网名: 猪头三
出生日期: 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){//调用委托方法来更新UImpr_action_UpdateRunInfo?.Invoke(mpu_int_ThreadIndex);// 如果不是第一个线程则直接等待mpr_event_State.WaitOne();}//调用委托方法来更新UImpr_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();}}}

[截图欣赏]
 

这篇关于[原创][6]探究C#多线程开发细节-“ConcurrentDictionary<T,T>解决多线程的无顺序性的问题“的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/468979

相关文章

C#如何调用C++库

《C#如何调用C++库》:本文主要介绍C#如何调用C++库方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录方法一:使用P/Invoke1. 导出C++函数2. 定义P/Invoke签名3. 调用C++函数方法二:使用C++/CLI作为桥接1. 创建C++/CL

MyBatis模糊查询报错:ParserException: not supported.pos 问题解决

《MyBatis模糊查询报错:ParserException:notsupported.pos问题解决》本文主要介绍了MyBatis模糊查询报错:ParserException:notsuppo... 目录问题描述问题根源错误SQL解析逻辑深层原因分析三种解决方案方案一:使用CONCAT函数(推荐)方案二:

Redis 热 key 和大 key 问题小结

《Redis热key和大key问题小结》:本文主要介绍Redis热key和大key问题小结,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录一、什么是 Redis 热 key?热 key(Hot Key)定义: 热 key 常见表现:热 key 的风险:二、

C#使用StackExchange.Redis实现分布式锁的两种方式介绍

《C#使用StackExchange.Redis实现分布式锁的两种方式介绍》分布式锁在集群的架构中发挥着重要的作用,:本文主要介绍C#使用StackExchange.Redis实现分布式锁的... 目录自定义分布式锁获取锁释放锁自动续期StackExchange.Redis分布式锁获取锁释放锁自动续期分布式

IntelliJ IDEA 中配置 Spring MVC 环境的详细步骤及问题解决

《IntelliJIDEA中配置SpringMVC环境的详细步骤及问题解决》:本文主要介绍IntelliJIDEA中配置SpringMVC环境的详细步骤及问题解决,本文分步骤结合实例给大... 目录步骤 1:创建 Maven Web 项目步骤 2:添加 Spring MVC 依赖1、保存后执行2、将新的依赖

SpringBoot中配置文件的加载顺序解读

《SpringBoot中配置文件的加载顺序解读》:本文主要介绍SpringBoot中配置文件的加载顺序,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录SpringBoot配置文件的加载顺序1、命令⾏参数2、Java系统属性3、操作系统环境变量5、项目【外部】的ap

Spring 中的循环引用问题解决方法

《Spring中的循环引用问题解决方法》:本文主要介绍Spring中的循环引用问题解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录什么是循环引用?循环依赖三级缓存解决循环依赖二级缓存三级缓存本章来聊聊Spring 中的循环引用问题该如何解决。这里聊

Spring Boot中JSON数值溢出问题从报错到优雅解决办法

《SpringBoot中JSON数值溢出问题从报错到优雅解决办法》:本文主要介绍SpringBoot中JSON数值溢出问题从报错到优雅的解决办法,通过修改字段类型为Long、添加全局异常处理和... 目录一、问题背景:为什么我的接口突然报错了?二、为什么会发生这个错误?1. Java 数据类型的“容量”限制

Go语言开发实现查询IP信息的MCP服务器

《Go语言开发实现查询IP信息的MCP服务器》随着MCP的快速普及和广泛应用,MCP服务器也层出不穷,本文将详细介绍如何在Go语言中使用go-mcp库来开发一个查询IP信息的MCP... 目录前言mcp-ip-geo 服务器目录结构说明查询 IP 信息功能实现工具实现工具管理查询单个 IP 信息工具的实现服

关于MongoDB图片URL存储异常问题以及解决

《关于MongoDB图片URL存储异常问题以及解决》:本文主要介绍关于MongoDB图片URL存储异常问题以及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录MongoDB图片URL存储异常问题项目场景问题描述原因分析解决方案预防措施js总结MongoDB图