[原创][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

相关文章

IDEA编译报错“java: 常量字符串过长”的原因及解决方法

《IDEA编译报错“java:常量字符串过长”的原因及解决方法》今天在开发过程中,由于尝试将一个文件的Base64字符串设置为常量,结果导致IDEA编译的时候出现了如下报错java:常量字符串过长,... 目录一、问题描述二、问题原因2.1 理论角度2.2 源码角度三、解决方案解决方案①:StringBui

C#中读取XML文件的四种常用方法

《C#中读取XML文件的四种常用方法》Xml是Internet环境中跨平台的,依赖于内容的技术,是当前处理结构化文档信息的有力工具,下面我们就来看看C#中读取XML文件的方法都有哪些吧... 目录XML简介格式C#读取XML文件方法使用XmlDocument使用XmlTextReader/XmlTextWr

mybatis和mybatis-plus设置值为null不起作用问题及解决

《mybatis和mybatis-plus设置值为null不起作用问题及解决》Mybatis-Plus的FieldStrategy主要用于控制新增、更新和查询时对空值的处理策略,通过配置不同的策略类型... 目录MyBATis-plusFieldStrategy作用FieldStrategy类型每种策略的作

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

linux下多个硬盘划分到同一挂载点问题

《linux下多个硬盘划分到同一挂载点问题》在Linux系统中,将多个硬盘划分到同一挂载点需要通过逻辑卷管理(LVM)来实现,首先,需要将物理存储设备(如硬盘分区)创建为物理卷,然后,将这些物理卷组成... 目录linux下多个硬盘划分到同一挂载点需要明确的几个概念硬盘插上默认的是非lvm总结Linux下多

Python Jupyter Notebook导包报错问题及解决

《PythonJupyterNotebook导包报错问题及解决》在conda环境中安装包后,JupyterNotebook导入时出现ImportError,可能是由于包版本不对应或版本太高,解决方... 目录问题解决方法重新安装Jupyter NoteBook 更改Kernel总结问题在conda上安装了

pip install jupyterlab失败的原因问题及探索

《pipinstalljupyterlab失败的原因问题及探索》在学习Yolo模型时,尝试安装JupyterLab但遇到错误,错误提示缺少Rust和Cargo编译环境,因为pywinpty包需要它... 目录背景问题解决方案总结背景最近在学习Yolo模型,然后其中要下载jupyter(有点LSVmu像一个

Goland debug失效详细解决步骤(合集)

《Golanddebug失效详细解决步骤(合集)》今天用Goland开发时,打断点,以debug方式运行,发现程序并没有断住,程序跳过了断点,直接运行结束,网上搜寻了大量文章,最后得以解决,特此在这... 目录Bug:Goland debug失效详细解决步骤【合集】情况一:Go或Goland架构不对情况二:

解决jupyterLab打开后出现Config option `template_path`not recognized by `ExporterCollapsibleHeadings`问题

《解决jupyterLab打开后出现Configoption`template_path`notrecognizedby`ExporterCollapsibleHeadings`问题》在Ju... 目录jupyterLab打开后出现“templandroidate_path”相关问题这是 tensorflo

SpringBoot中使用 ThreadLocal 进行多线程上下文管理及注意事项小结

《SpringBoot中使用ThreadLocal进行多线程上下文管理及注意事项小结》本文详细介绍了ThreadLocal的原理、使用场景和示例代码,并在SpringBoot中使用ThreadLo... 目录前言技术积累1.什么是 ThreadLocal2. ThreadLocal 的原理2.1 线程隔离2