• WaitHandles 的数目必须少于或等于 64 个任意线程信号量监视


    WaitHandles 的数目必须少于或等于 64 个 当开启的ManualResetEvent 实例数据大于64个之后,系统就会抛出此错误。

    但在实际项目中,我需要请求多线程的数量在很多情况下都会超过 64个,为了解决这个限制。 才用一个信号量来监控多个线程的方式实现,即可开启任意一个线程。

    //1  首先自己封装一个 信号量类 :

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    namespace AutoGenMarketPriceData.BLL
    {
        /// <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 Set()
            {
                // 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();
            }
        }
    }

     

    //2  调用示例

            public void BeginGeneratePriceDatas()
            {
    #if !DEBUG
                //设置10个线程
                ThreadPool.SetMaxThreads(10, 10); 
                MultiThreadResetEvent threadEvent = new MultiThreadResetEvent();
    #endif
                foreach (Area bsyArea in bsyAreaLists)
                {
                    foreach (Menu menu in menuList)
                    {
    #if DEBUG
                        //debug使用单线程方便调试
                        DoTaskOneThread(bsyArea, menu); 
    #else
                        //release 版本使用多线程处理
                        threadEvent.addWaitOne();     //加入一个需要监控的线程
                        ThreadModel model = new ThreadModel()
                        {
                            BsyArea = bsyArea,
                            BsyMenu = menu,
                            CurrentWaitHandle = threadEvent
                        };
                        ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), model);
    #endif
                    }
                }
    #if !DEBUG
                threadEvent.WaitAll();
                threadEvent.Dispose();
    #endif
            }

    //在该方法中,线程执行完毕,减少监控的线程

    public void DoTask(object state)
         {
             //AutoResetEvent are = (AutoResetEvent)state;

             ThreadModel currentModel = (ThreadModel)state;
             MultiThreadResetEvent are = (MultiThreadResetEvent)currentModel.CurrentWaitHandle;
             Area bsyArea = currentModel.BsyArea;
             Menu menu = currentModel.BsyMenu;

             DoTaskOneThread(bsyArea, menu);

             are.Set();
         }

     

    // 可以参照我的调用示例 自己修改下。

  • 相关阅读:
    calendar的用法
    为什么要初始化变量呢
    什么情况下,if()后面的else可以省略不写
    new 对象的时候,括号里有值和无值的区别
    if...else...;if..else if...else
    java-csv导出-导出文件显示的日期格式不正确
    使用Navicat连接MySQL,连接失败(报1064错误)
    MySQL下载安装详解(win10)
    Syntax error, parameterized types are only available if source level is 1.5 or greater
    eclipse ant出错问题
  • 原文地址:https://www.cnblogs.com/iampkm/p/3095219.html
Copyright © 2020-2023  润新知