在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
网上找的,做个笔记记录一下。 有这么一个需求,就是巡检多台服务器是否都在线,点击巡检按钮后,按行读取DataGridView中的数据,并启行线程执行,这时会存在多个线程同时运行,但是什么时候给出用户提醒,说都巡检完成了呢,需要用到一个线程状态的检测。 最后的效果是这样子的,多个线程对表格按行进行服务器的巡检,只有等所有的巡检线都结束后,等待线程才会弹出一个巡检完毕的提示框,在巡检的过程中,不会卡主界面。 1、新建一个类,用于处理线程状态的计数,用于解决EventWaitHandle时线程不能超过64个的问题public class MutipleThreadResetEvent : IDisposable { private readonly ManualResetEvent done; private readonly int total; private long current; /// <summary> /// 构造函数 /// </summary> /// <param name="total">需要等待执行的线程总数</param> public MutipleThreadResetEvent(int total) { this.total = total; current = total; done = new ManualResetEvent(false); } /// <summary> /// 唤醒一个等待的线程 /// </summary> public void SetOne() { // Interlocked 原子操作类 ,此处将计数器减1 if (Interlocked.Decrement(ref current) == 0) { //当所以等待线程执行完毕时,唤醒等待的线程 done.Set(); } } /// <summary> /// 等待所以线程执行完毕 /// </summary> public void WaitAll() { done.WaitOne(); } /// <summary> /// 释放对象占用的空间 /// </summary> public void Dispose() { ((IDisposable)done).Dispose(); } } 2、定义一个结构体,用于存放线程需要的参数和MutipleThreadResetEventstruct webInfo { public int xh; public string lx; public string path; public object mre; //public ManualResetEvent mre; } 3、在DataGridView中使用int num = DG_show.RowCount - 1; for (int i = 0; i < DG_show.RowCount - 1; i++) { DG_show.Rows[i].Cells["验证结果"].Value = ""; DG_show.Rows[i].DefaultCellStyle.BackColor = Color.White; } //开始进行验证 //manualEvents.Clear(); //以前的代码,可以删除 PR1.Maximum = num; PR1.Minimum = 0; var countdown = new MutipleThreadResetEvent(num); webInfo info1; ThreadPool.SetMaxThreads(5,5); //设置最大的线程数量 for (int i = 0; i < DG_show.RowCount - 1; i++) { //ManualResetEvent mre = new ManualResetEvent(false); //manualEvents.Add(mre); info1.xh = i; //info1.mre = mre; info1.mre = countdown; info1.lx = DG_show.Rows[i].Cells["方式"].Value.ToString().Trim(); info1.path = DG_show.Rows[i].Cells["地址"].Value.ToString().Trim(); //Thread thread1 = new Thread(new ParameterizedThreadStart(CheckResult)); //thread1.Start(info1); CheckResult和WaitThreadEnd就是具体的业务处理
4、巡检线程和等待线程中的写法巡检线程 private void CheckResult(object info) { webInfo web = (webInfo)info; //... ...省略掉具体的业务过程 MutipleThreadResetEvent countdown = web.mre as MutipleThreadResetEvent; countdown.SetOne(); } 等待巡检线程执行完毕的等待线程,其中执行一些启用主ui界面控件显示,进度条控件,按钮控件等操作,但是弹出的对话框有点问题,是在线程中弹出的,用户可能关注不到它。 public void WaitThreadEnd(object obj) { MutipleThreadResetEvent countdown = obj as MutipleThreadResetEvent; countdown.WaitAll();
运行起来后效果还不错,对于我们这种小白用户可以解决大部分的问题了。 |
请发表评论