ManualResetEvent多线程进行,全部完成后,回调

static void Main(string[] args)
        {
            int count = 10;
            ManualResetEvent[] manuas = new ManualResetEvent[count];
            for (int i = 0; i < count; i++)
            {
                manuas[i] = new ManualResetEvent(false);
                //封装对象,进行传值
                ThreadPool.QueueUserWorkItem(new WaitCallback(testMethod), new aaa() { manualResetEvent=manuas[i], name="name"+i });
            }
            if (WaitHandle.WaitAll(manuas))
            { //All threads have completed.
                Console.WriteLine("true");
            }
            else
            {
                Console.WriteLine("false");
            }
            Console.ReadKey();
        }

        public static void testMethod(object j)
        {
            //TODO: Add your code here
            //转化对象,do with data
            aaa a = j as aaa;
            if (a != null)
            {
                for (int i = 0; i < 1000; i++)
                {
                    Console.WriteLine(a.name+"==>" + i);
                }

                ManualResetEvent e = a.manualResetEvent;
                e.Set();
            }
            else
            {
                Console.WriteLine("传值失败");
            }

        }


class aaa
    {
        public ManualResetEvent manualResetEvent { get; set; }
        public string name { get; set; }
    }

    

以上有个bug:当线程数大于64个之后抛出异常

解决方法

封装一个MutipleThreadResetEvent类,

(1)封装MutipleThreadResetEvent类

using System;
using System.Threading;

namespace ConsoleApp5
{
    class MutipleThreadResetEvent : IDisposable
    {
        private readonly ManualResetEvent done;

        /// <summary>
        /// 需要等待执行的线程总数。
        /// </summary>
        public readonly int total;

        /// <summary>
        /// 计数器:当前还有的多少个线程数
        /// </summary>
        private long current;


        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="total">需要等待执行的线程总数</param>
        public MutipleThreadResetEvent(int total)
        {
            this.total = total;
            current = total;
            done = new ManualResetEvent(false);
        }

        public void SetDone()
        {
            //每一个子线程完成时-1
            long lon = Interlocked.Decrement(ref current);
            if (lon == 0)
            {//到0时,向主线程发出信号,已经完成所有子线程操作,不用等了,进行下一步操作。
                done.Set();
            }
           
        }

        /// <summary>
        /// 等待所有线程执行完毕
        /// </summary>
        public void WaitAll()
       {
            this.done.WaitOne();
        }

        /// <summary>
        /// 释放对象占用的空间
        /// </summary>
        public void Dispose()
        {
            ((IDisposable)done).Dispose();
        }
    }
}
View Code

(2)进行调用

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApp5
{
    class Program
    {

        static void Main(string[] args)
        {
            int num = 100;
            using (MutipleThreadResetEvent countdown = new MutipleThreadResetEvent(num))
            {
                for (int i = 0; i < num; i++)
                {
                    //开启num个线程(text),传递MutipleThreadResetEvent对象(countdown)给子线程(text)
                    ThreadPool.QueueUserWorkItem(text, countdown);
                }
                //等待所有线程执行完毕
                countdown.WaitAll();
            }
            Console.WriteLine("已经完事了");
            //进行下一步操作。

            Console.ReadKey();
        }

        public static void text(object obj)
        {
            //|自己的操作
            Console.WriteLine(""+(i++));

            //接收参数
            MutipleThreadResetEvent man = obj as MutipleThreadResetEvent;
            if (man == null)
            {
                Console.WriteLine("传值失败");
            }
            else
            {
                //发送信号量 本线程执行完毕
                man.SetDone();
            }
        }
    }
}
View Code

注意:在winform中会出现程序假死,那就再new Thread(delegate(){ dosth }){}.Start();吧!!

原文地址:https://www.cnblogs.com/wwz-wwz/p/8563743.html