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单元格显示图片

热门文章

无法握住的故土 在我们心灵最温暖的角落,总有一寸土地是属于故乡的。虽然我们看似已远离故土,可骨子里对故乡的依恋却是从未冷却过。我们无论漂泊他乡,还是在繁华都市平步青云,可故乡的悠悠情思总会潜入梦乡与你缠绵。是儿时那一缕缕茉莉的清香萦绕在梦境,也是邻家那已锈迹斑斑的铁壶里,开出艳丽的花儿在梦的边缘摇曳。故土就这样根深蒂固地在我们的灵魂深处烙下深深的印记。 作者:Pastore Antonio
1596 浏览量
EWS(Exchange Service)基本使用(获取个人会议,会议室会议内容,会议室列表,发送会议,修改会议,删除会议) 最近公司要求和exchange服务对接,所以稍微研究了一下官方文档,做出以下总结,欢迎大家补充。先...EWS(ExchangeService)基本使用(获取个人会议,会议室会议内容,会议室列表,发送会议,修改会议,删除会议) 作者:Pastore Antonio
1585 浏览量
Sql Server 部署SSIS包完成远程数据传输 本篇介绍如何使用SSIS和作业完成自动更新目标数据任务。**温馨提示:如需转载本文,请注明...SqlServer部署SSIS包完成远程数据传输 作者:Pastore Antonio
1579 浏览量
SQL Server AG集群启动不起来的临时自救大招 背景前晚一朋友遇到AG集群发生来回切换不稳定的情况,情急之下,朋友在命令行使用命令重启WSFC集群...SQLServerAG集群启动不起来的临时自救大招 作者:Pastore Antonio
1573 浏览量
windows 下安装 memcahce 官网上并未提供Memcached的Windows平台安装包,我们可以使用以下链接来下载,你需...windows下安装memcahce 作者:Pastore Antonio
1567 浏览量