C# 多线程等待子线程全部完成 ThreadPool

 private void button1_Click(object sender, EventArgs e)
        { 
            
            //假设有10个请求线程
            int num = 10;
            using (MultiThreadResetEvent multiThreadResetEvent = new MultiThreadResetEvent(num))
            {
                for (int i = 0; i < num; i++)
                {
                    //ManualResetEvent manualResetEvent = new ManualResetEvent(false);
                    Param pra = new Param();
                    pra.multiThreadResetEvent = multiThreadResetEvent;
                    pra.value = i;
                    //manualResetEvents.Add(manualResetEvent);
                    ThreadPool.QueueUserWorkItem(Call, pra);

                }
                //WaitHandle.WaitAll(manualResetEvents.ToArray());

                multiThreadResetEvent.WaitAll();
            }
       
            Console.WriteLine("main thread is success");
        }

  

  private void Call(object state)
        {
            Thread.Sleep(1000);
            Param param = state as Param;


            Console.WriteLine($"Thread execute {param.value} --- {DateTime.Now}  ");
            param.multiThreadResetEvent.SetOne(); 
        }

  

    public  class Param
    {
        public Param()
        {
        }

        public MultiThreadResetEvent multiThreadResetEvent { get;  set; }
        public int value { get;  set; }
    }

  

  /// <summary>
    /// 多线程信号等待
    /// </summary>
    public class MultiThreadResetEvent : IDisposable
    {
        private readonly ManualResetEvent done;
        private readonly int total;
        private long current;

        /// <summary>
        /// 监视total个线程执行(线程数固定,可以超过64个)
        /// </summary>
        /// <param name="total">需要等待执行的线程总数</param>
        public MultiThreadResetEvent(int total)
        {
            this.total = total;
            current = total;
            done = new ManualResetEvent(false);
        }

        /// <summary>
        /// 线程数不固定,监视任意线程数时
        /// </summary>
        public MultiThreadResetEvent()
        {
            done = new ManualResetEvent(false);
        }

        /// <summary>
        /// 加入一个要等待的线程信号
        /// </summary>
        public void addWaitOne()
        {
            Interlocked.Increment(ref current);
        }
        /// <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();
        }
    }

  测试

 

posted @ 2021-12-12 10:36  JohnnyLei  阅读(188)  评论(0)    收藏  举报