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
1451 浏览量
【干货】Chrome插件(扩展)开发全攻略 写在前面我花了将近一个多月的时间断断续续写下这篇博文,并精心写下完整demo,写博客的辛苦大家懂的...【干货】Chrome插件(扩展)开发全攻略 作者:Pastore Antonio
1415 浏览量
CentOS 编译错误+配置错误解决方法集合 ERROR:theHTTPXSLTmodulerequiresthelibxml2/l...CentOS编译错误+配置错误解决方法集合 作者:Pastore Antonio
1409 浏览量
WordPress中加载JavaScript脚本的方法 在WordPress中加载脚本(为CSS和JS,下同)文件,大多数人的做法是直接在hea...WordPress中加载JavaScript脚本的方法 作者:Pastore Antonio
1385 浏览量
wordpress学习五: 通过wordpress_xmlrpc的python包远程操作wordpress wordpress提供了丰富的xmlrpc接口api来供我们远程操控wp的内容。伟大的开源社区有人就...wordpress学习五:通过wordpress_xmlrpc的python包远程操作wordpress 作者:Pastore Antonio
1382 浏览量