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();
            }
        }
  • 相关阅读:
    Windows 获取unix timestamp
    SQL Server 2008 R2:快速清除日志文件的方法
    mysql lost connection to server during query
    jquery 隐藏 显示 动画效果
    session
    javaScript日期
    路径惹的祸
    Declaration terminated incorrectly 讨厌 这样就不可以了
    jsp 调用其他jsp页面 跳转
    SQL 2008 启用和禁用xp_cmdshell
  • 原文地址:https://www.cnblogs.com/xwcs/p/13508542.html
Copyright © 2011-2022 走看看