zoukankan      html  css  js  c++  java
  • 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();吧!!

  • 相关阅读:
    Angular InjectionToken
    ionic 使用入门
    EFcore 横向分表
    .Netcore 默认认证授权
    anut 设计资源
    Aunt entity
    百度人脸真人认证
    Angular 省市区级联
    apache安装
    ppb|ppm
  • 原文地址:https://www.cnblogs.com/wwz-wwz/p/8563743.html
Copyright © 2011-2022 走看看