宛城区网站建设,保定网络营销网站建设,网络营销方法和手段,餐厅网站建设[简介] 常用网名: 猪头三 出生日期: 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、D…[简介] 常用网名: 猪头三 出生日期: 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应用软件安全 项目经历: 磁盘性能优化/文件系统数据恢复/文件信息采集/敏感文件监测跟踪/网络安全检测
[序言] 如果大家认真地阅读了[原创][3]探究C#多线程开发细节-“用ConcurrentQueueT解决多线程的无顺序性的问题这篇文章, 就会发现里面的多线程同步机制是非常低效且愚蠢的. 那么如何解决这样的问题呢 那就是利用[原创][4]探究C#多线程开发细节-初步体验ManualResetEvent类带来的同步效果介绍的事件机制来处理这类棘手的问题.
[利用AutoResetEvent类来强制10个线程依次结束, 大概编程逻辑如下: ]1 for循环创建每一个线程的时候, 为每个线程赋予一个索引号和AutoResetEvent类变量.2 为每一个线程对应的AutoResetEvent类变量放入队列ConcurrentQueueT中.3 当每个线程要结束之前, 都执行AutoResetEvent的WaitOne()等待.
通过上面的3步骤处理, 就可以达到10个线程依次结束效果.比如: 0号线程结束之后, 轮到1号线程结束. 1号线程结束之后, 轮到2号线程结束...依次类推.
[10个线程依次结束的过程中, 它们之间是如何响应的呢?] 假设如下情况:1 2号线程比1号线程提前准备进入终点, 但是在进入终点之前执行了WaitOne()等待, 目的就是等待1号线程是否已经进入终点了. 2 此时1号线程没有进入终点, 那么2号线程会一直在终点前等待1号线程.3 当1号线程进入终点之后, 就针对2号线程的AutoResetEvent执行一次set()通知2号线程, 我已经进入终点了, 轮到你进去了.
依次类推可以应用到其他线程的关系, 就是这简单的3步骤内部通信逻辑, 就能让0号线程~9号线程, 有序的步入终点(即结束线程任务).
[下面是一套完整的代码] 这里要特别理解这2行代码
AutoResetEvent event_Next mpr_cq_ThreadEvent.ToArray()[mpu_int_ThreadIndex 1];
event_Next.Set(); public partial class Form_Main : Form{private ConcurrentQueueAutoResetEvent mpr_cq_ThreadEvent new ConcurrentQueueAutoResetEvent();public class Thread_Run{public int mpu_int_ThreadIndex;private Actionint mpr_action_UpdateWaiteInfo;private ConcurrentQueueAutoResetEvent mpr_cq_ThreadEvent;private AutoResetEvent mpr_event_State;public Thread_Run(Actionint action_param_UpdateWaiteInfo, ref ConcurrentQueueAutoResetEvent cq_param_ThreadEvent, object obj_param_EventState){mpr_action_UpdateWaiteInfo action_param_UpdateWaiteInfo;mpr_cq_ThreadEvent cq_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(){if (mpu_int_ThreadIndex ! 0){// 如果不是第一个线程则直接等待mpr_event_State.WaitOne();}//调用委托方法来更新UImpr_action_UpdateWaiteInfo?.Invoke(mpu_int_ThreadIndex);// 通知当前线程的下一个线程放弃等待,可直接返回// 比如当前是1号线程那么它的下一个就是2号线程if (mpu_int_ThreadIndex 1 mpr_cq_ThreadEvent.Count()){AutoResetEvent event_Next mpr_cq_ThreadEvent.ToArray()[mpu_int_ThreadIndex 1];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));});}}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_cq_ThreadEvent.Enqueue(var_ThreadEvent);Thread_Run class_ThreadRun new Thread_Run(mpu_pro_UpdateWaiteInfo, ref mpr_cq_ThreadEvent, var_ThreadEvent);class_ThreadRun.mpu_int_ThreadIndex int_Index;class_ThreadRun.mpu_pro_StartThread();}}}
[结尾] 这份代码的完美度达到了95%, 但还有更完美的写法, 就是利用ConcurrentDictionaryT类来代替ConcurrentQueueT类, 并管理AutoResetEvent事件. 下一篇我们将会继续优化代码