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

2023-12-14 18:13:03

[简介]
常用网名: 猪头三
出生日期: 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();
                
            }

        }

    }

[截图欣赏]
?

文章来源:https://blog.csdn.net/Code_GodFather/article/details/134867384
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。