Logo

C#多线程等待所有子线程结束

photo

2022年06月30日

在使用多线程过程中,可能会遇到在一些情况下必须等待子线程全部执行结束后主线程才进行下一步,

做法如下:

 //在使用多线程过程中,可能会遇到在一些情况下必须等待子线程全部执行结束后主线程才进行下一步,做法如下
            List<ManualResetEvent> manualEvents = new List<ManualResetEvent>();//创建线程等待集合
            for (int i = 0; i < 64; i++) //WaitHandles 的数目必须少于或等于 64 个,所以最大线程数为64
            {
                MB m = new MB();//自定义类,用于传参
                m.mre= new ManualResetEvent(false);
                m.ID = i;

                manualEvents.Add(m.mre);
                ThreadPool.QueueUserWorkItem(ThreadMethod, m);
            }
            WaitHandle.WaitAll(manualEvents.ToArray());//等待所有线程结束
            Console.WriteLine("Thread Finished!");
private static void ThreadMethod(object obj)
        {
            MB m = (MB)obj;
            Thread.Sleep(1000);//等待1秒,用于模拟系统在处理事情
            m.mre.Set();//将事件设置为终止状态
            Console.WriteLine("Thread execute:" + m.ID);
        }

 

以上方法在处理时当线程数超过64时报错 WaitHandles 的数目必须少于或等于 64 个,所以最大线程数为64
解决方法如下:

                using (var countdown = new MutipleThreadResetEvent(list.Count))
                {
                    for (int i = 0; i < list.Count; i++)
                    {
                        //开启N个线程,传递MutipleThreadResetEvent对象给子线程
                        Param p = new Param();
                        p.countdown = countdown;
                        p.Path = pa[i];
                        ThreadPool.QueueUserWorkItem(MyHttpRequest, p);
                    }

                    //等待所有线程执行完毕
                    countdown.WaitAll();
                }
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();
        }
    }

 

橙子主题打折出售

其实我不卖,主要是这里是放广告的,所以就放了一个
毕竟主题都没做完,卖了也是坑.

购买它
所有附件
该文章没有附件.
本文为原创文章,请注意保留出处!

单元格显示特定图片的功能还是比较简单的,只是网上的资料很多,太乱。现在就给大家写个很简单的方法供大家...C#WinForm中DataGridView单元格显示图片

热门文章

WordPress 后台编辑器样式实现直接预览 在WordPress3.0以后,有一个新的实用功能:你可以更改默认后台编辑器(TinyMCE)的样...WordPress后台编辑器样式实现直接预览 作者:Pastore Antonio
1533 浏览量
【干货】Chrome插件(扩展)开发全攻略 写在前面我花了将近一个多月的时间断断续续写下这篇博文,并精心写下完整demo,写博客的辛苦大家懂的...【干货】Chrome插件(扩展)开发全攻略 作者:Pastore Antonio
1488 浏览量
memcached 处理 多端口:https://blog.csdn.net/Erica_1230/article/deta...memcached处理 作者:Pastore Antonio
1481 浏览量
使用Nginx+WordPress搭建个人网站 背景很多研究技术的朋友喜欢写博客。如果希望搭建一个完全属于自己的网站,也并不困难。这里简要分享一下...使用Nginx+WordPress搭建个人网站 作者:Pastore Antonio
1453 浏览量
C#图片处理 通常对一幅图片的处理包括:格式变换,缩放(Scale),翻转(Rotate),截取(Clip),滤镜...C#图片处理 作者:Pastore Antonio
1445 浏览量