zoukankan      html  css  js  c++  java
  • C#多线程等待所有子线程结束

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

    做法如下:

     //在使用多线程过程中,可能会遇到在一些情况下必须等待子线程全部执行结束后主线程才进行下一步,做法如下
                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();
            }
        }
  • 相关阅读:
    第一道题:无头苍蝇装头术(望不吝赐教)
    jdk8 list是否包含某值的一些应用
    Failed to close server connection after message failures; nested exception is javax.mail.MessagingException: Can't send command to SMTP host
    itext pdf加密
    TiDB-禁用遥测功能
    TiDB-配置调整
    DM-表空间
    DM-INI参数配置
    DM-DSC集群配置
    PG-并行查询
  • 原文地址:https://www.cnblogs.com/xwcs/p/13508542.html
Copyright © 2011-2022 走看看