原文网址: http://www.cnblogs.com/csdev

Networkcomms 是一款C# 语言编写的TCP/UDP通信框架  作者是英国人  以前是收费的 目前作者已经开源  许可是:Apache License v2

开源地址是:https://github.com/MarcFletcher/NetworkComms.Net

自定义线程池,用于并发处理通信框架收到的消息

  /// <summary>
    /// A compact priority based thread pool used by NetworkComms.Net to run packet handlers
    /// 支持优先级处理的自定义线程池
    /// </summary>
    public class CommsThreadPool
    {
        /// <summary>
        /// A sync object to make things thread safe
        /// 同步锁
        /// </summary>
        object SyncRoot = new object();

        /// <summary>
        /// Dictionary of threads, index is ThreadId
        /// 线程字典  索引是线程ID
        /// </summary>
        Dictionary<int, Thread> threadDict = new Dictionary<int, Thread>();

        /// <summary>
        /// Dictionary of thread worker info, index is ThreadId
        /// 线程工作者字典   索引是线程ID
        /// </summary>
        Dictionary<int, WorkerInfo> workerInfoDict = new Dictionary<int, WorkerInfo>();

        /// <summary>
        /// The minimum timespan between thread wait sleep join updates
        /// 线程 等待  睡眠 加入 更新 的一个最小时间段
        /// </summary>
        TimeSpan ThreadWaitSleepJoinCountUpdateInterval = , , , , );

        /// <summary>
        /// A quick lookup of the number of current threads which are idle and require jobs
        /// 正在等待任务的线程数量
        /// </summary>
        ;

        /// <summary>
        /// Priority queue used to order call backs
        /// 用于处理回调委托的优先级队列
        /// </summary>
        PriorityQueue<WaitCallBackWrapper> jobQueue = new PriorityQueue<WaitCallBackWrapper>();

        /// <summary>
        /// Set to true to ensure correct shutdown of worker threads.
        /// 是否关闭
        /// </summary>
        bool shutdown = false;

        /// <summary>
        /// The timespan after which an idle thread will close
        /// 线程空闲多长时间将会关闭
        /// </summary>
        TimeSpan ThreadIdleTimeoutClose { get; set; }

        /// <summary>
        /// The maximum number of threads to create in the pool
        /// 最大的线程数
        /// </summary>
        public int MaxTotalThreadsCount { get; private set; }

        /// <summary>
        /// The maximum number of active threads in the pool. This can be less than MaxTotalThreadsCount, taking account of waiting threads.
        /// 线程池中活动线程的最大数量
        /// </summary>
        public int MaxActiveThreadsCount { get; private set; }

        /// <summary>
        /// The minimum number of idle threads to maintain in the pool
        /// 最小线程数
        /// </summary>
        public int MinThreadsCount { get; private set; }

        /// <summary>
        /// The most recent count of pool threads which are waiting for IO
        /// 正在等待的线程数
        /// </summary>
        public int CurrentNumWaitSleepJoinThreadsCache { get; private set; }

        /// <summary>
        /// The dateTime associated with the most recent count of pool threads which are waiting for IO
        ///
        /// </summary>
        public DateTime LastThreadWaitSleepJoinCountCacheUpdate { get; private set; }

        /// <summary>
        /// The total number of threads currently in the thread pool
        /// 当前的线程数
        /// </summary>
        public int CurrentNumTotalThreads
        {
            get { lock (SyncRoot) return threadDict.Count; }
        }

        /// <summary>
        /// The total number of idle threads currently in the thread pool
        /// 当前空闲的线程数
        /// </summary>
        public int CurrentNumIdleThreads
        {
            get { lock (SyncRoot) return requireJobThreadsCount; }
        }

        /// <summary>
        /// The total number of items currently waiting to be collected by a thread
        /// 队列数量
        /// </summary>
        public int QueueCount
        {
            get { return jobQueue.Count; }
        }

        /// <summary>
        /// Create a new NetworkComms.Net thread pool
        /// 创建一个新的自定义线程池
        /// </summary>
        /// <param name="minThreadsCount">最小线程数 Minimum number of idle threads to maintain in the pool</param>
        /// <param name="maxActiveThreadsCount">最大活动线程数 The maximum number of active (i.e. not waiting for IO) threads</param>
        /// <param name="maxTotalThreadsCount">最大线程数 Maximum number of threads to create in the pool</param>
        /// <param name="threadIdleTimeoutClose">空闲多长时间线程被关闭  Timespan after which an idle thread will close</param>
        public CommsThreadPool(int minThreadsCount, int maxActiveThreadsCount, int maxTotalThreadsCount, TimeSpan threadIdleTimeoutClose)
        {
            MinThreadsCount = minThreadsCount;
            MaxTotalThreadsCount = maxTotalThreadsCount;
            MaxActiveThreadsCount = maxActiveThreadsCount;
            ThreadIdleTimeoutClose = threadIdleTimeoutClose;
        }

        /// <summary>
        /// Prevent any additional threads from starting. Returns immediately.
        /// 关闭   系统不会再创建新的线程
        /// </summary>
        public void BeginShutdown()
        {
            lock (SyncRoot)
                shutdown = true;
        }

        /// <summary>
        /// Prevent any additional threads from starting and return once all existing workers have completed.
        /// 不再创建新的线程 当前工作都完成后就返回
        /// </summary>
        /// <param name="threadShutdownTimeoutMS"></param>
        )
        {
            List<Thread> allWorkerThreads = new List<Thread>();
            lock (SyncRoot)
            {
                foreach (var thread in threadDict)
                {
                    workerInfoDict[thread.Key].ThreadSignal.Set();
                    allWorkerThreads.Add(thread.Value);
                }
            }

            //Wait for all threads to finish 等待所有线程完成
            foreach (Thread thread in allWorkerThreads)
            {
                try
                {
                    if (!thread.Join(threadShutdownTimeoutMS))
                        thread.Abort();
                }
                catch (Exception ex)
                {
                    LogTools.LogException(ex, "ManagedThreadPoolShutdownError");
                }
            }

            lock (SyncRoot)
            {
                jobQueue.Clear();
                shutdown = false;
            }
        }

        /// <summary>
        ///  Enqueue a callback to the thread pool.
        ///  给线程池添加要处理的任务
        /// </summary>
        /// <param name="priority">优先级  The priority with which to enqueue the provided callback</param>
        /// <param name="callback">回调方法(用于处理进入的数据)  The callback to execute</param>
        /// <param name="state">通信框架解析好的数据   The state parameter to pass to the callback when executed</param>
        /// <returns>Returns the managed threadId running the callback if one was available, otherwise -1</returns>
        public int EnqueueItem(QueueItemPriority priority, WaitCallback callback, object state)
        {
            ;

            lock (SyncRoot)
            {
                UpdateThreadWaitSleepJoinCountCache();

                , threadDict.Count - CurrentNumWaitSleepJoinThreadsCache - requireJobThreadsCount);

                //int numActiveThreads = Math.Max(0,threadDict.Count - CurrentNumWaitSleepJoinThreadsCache);
                 && numInJobActiveThreadsCount < MaxActiveThreadsCount && threadDict.Count < MaxTotalThreadsCount)
                {
                    //Launch a new thread 启动一个新线程
                    Thread newThread = new Thread(ThreadWorker);
                    newThread.Name = "ManagedThreadPool_" + newThread.ManagedThreadId.ToString();
                    newThread.IsBackground = true;

                    WorkerInfo info = new WorkerInfo(newThread.ManagedThreadId, new WaitCallBackWrapper(callback, state));

                    chosenThreadId = newThread.ManagedThreadId;
                    threadDict.Add(newThread.ManagedThreadId, newThread);
                    workerInfoDict.Add(newThread.ManagedThreadId, info);

                    newThread.Start(info);
                }
                 && numInJobActiveThreadsCount < MaxActiveThreadsCount)
                {
                    jobQueue.TryAdd(new KeyValuePair<QueueItemPriority, WaitCallBackWrapper>(priority, new WaitCallBackWrapper(callback, state)));

                    ;

                    foreach (var info in workerInfoDict)
                    {
                        //Trigger the first idle thread 触发第一个空闲线程
                        checkCount++;
                        if (info.Value.ThreadIdle)
                        {
                            info.Value.ClearThreadIdle();
                            requireJobThreadsCount--;

                            info.Value.ThreadSignal.Set();
                            chosenThreadId = info.Value.ThreadId;

                            break;
                        }

                        if (checkCount == workerInfoDict.Count)
                            throw new Exception("IdleThreads count is " + requireJobThreadsCount.ToString() + " but unable to locate thread marked as idle.");
                    }
                }
                else if (!shutdown)
                {
                    //If there are no idle threads and we can't start any new ones we just have to enqueue the item
                    //如果没有空闲线程 我们不能启动新线程 只是把任务添加到队列中
                    jobQueue.TryAdd(new KeyValuePair<QueueItemPriority, WaitCallBackWrapper>(priority, new WaitCallBackWrapper(callback, state)));
                }
            }

            return chosenThreadId;
        }

        /// <summary>
        /// The worker object for the thread pool
        /// 线程池的工作者方法
        /// </summary>
        /// <param name="state"></param>
        private void ThreadWorker(object state)
        {
            WorkerInfo threadInfo = (WorkerInfo)state;

            do
            {
                //While there are jobs in the queue process the jobs
                //处理队列中的任务
                while (true)
                {
                    if (threadInfo.CurrentCallBackWrapper == null)
                    {
                        KeyValuePair<QueueItemPriority, WaitCallBackWrapper> packetQueueItem;
                        lock (SyncRoot)
                        {
                            UpdateThreadWaitSleepJoinCountCache();
                            , threadDict.Count - CurrentNumWaitSleepJoinThreadsCache - requireJobThreadsCount);

                            if (shutdown || threadDict.Count > MaxTotalThreadsCount) //If we have too many active threads
                            {
                                //If shutdown was true then we may need to set thread to idle
                                //如果  shutdown设置为True  我们需要设置线程为空闲
                                )
                                    requireJobThreadsCount--;

                                threadInfo.ClearThreadIdle();

                                threadDict.Remove(threadInfo.ThreadId);
                                workerInfoDict.Remove(threadInfo.ThreadId);

                                UpdateThreadWaitSleepJoinCountCache();
                                return;
                            }
                            else if (numInJobActiveThreadsCount > MaxActiveThreadsCount) //If we have too many active threads 活动的线程太多
                            {
                                //We wont close here to prevent thread creation/destruction thrashing.
                                //We will instead act as if there is no work and wait to potentially be timed out
                                if (!threadInfo.ThreadIdle)
                                {
                                    threadInfo.SetThreadIdle();
                                    requireJobThreadsCount++;
                                }

                                break;
                            }
                            else
                            {
                                //Try to get a job 获取一个新任务
                                if (!jobQueue.TryTake(out packetQueueItem)) //We fail to get a new job  没有获取到新任务
                                {
                                    //If we failed to get a job we switch to idle and wait to be triggered
                                    //如果没有获取到任务 转为空闲状态并等待被触发
                                    if (!threadInfo.ThreadIdle)
                                    {
                                        threadInfo.SetThreadIdle();
                                        requireJobThreadsCount++;
                                    }

                                    break;
                                }
                                else
                                {
                                    )
                                        requireJobThreadsCount--;

                                    threadInfo.UpdateCurrentCallBackWrapper(packetQueueItem.Value);
                                    threadInfo.ClearThreadIdle();
                                }
                            }
                        }
                    }

                    //Perform the waitcallBack
                    //执行回调方法
                    try
                    {
                        threadInfo.SetInsideCallBack();
                        threadInfo.CurrentCallBackWrapper.WaitCallBack(threadInfo.CurrentCallBackWrapper.State);
                    }
                    catch (Exception ex)
                    {
                        LogTools.LogException(ex, "ManagedThreadPoolCallBackError", "An unhandled exception was caught while processing a callback. Make sure to catch errors in callbacks to prevent this error file being produced.");
                    }
                    finally
                    {
                        threadInfo.ClearInsideCallBack();
                    }

                    threadInfo.UpdateLastActiveTime();
                    threadInfo.ClearCallBackWrapper();
                }

                //As soon as the queue is empty we wait until perhaps close time
                //当队列为空时 就是当前没有可以处理的任务  线程进行等待 直到超过某个时间
#if NET2
                , false))
#else
                ))
#endif
                {
                    //While we are waiting we check to see if we need to close
                    //线程如果等待了太长时间  又没有新任务来 关闭线程
                    if (DateTime.Now - threadInfo.LastActiveTime > ThreadIdleTimeoutClose)
                    {
                        lock (SyncRoot)
                        {
                            //We have timed out but we don't go below the minimum
                            //如果当前线程池中的线程数太少,接近最小线程数,则不再关闭线程
                            if (threadDict.Count > MinThreadsCount)
                            {
                                )
                                    requireJobThreadsCount--;

                                threadInfo.ClearThreadIdle();

                                threadDict.Remove(threadInfo.ThreadId);
                                workerInfoDict.Remove(threadInfo.ThreadId);

                                UpdateThreadWaitSleepJoinCountCache();
                                return;
                            }
                        }
                    }
                }

                //We only leave via one of our possible breaks
            } while (true);
        }

        /// <summary>
        /// Returns the total number of threads in the pool which are waiting for IO
        /// 返回在等待IO库总的线程数
        /// </summary>
        private void UpdateThreadWaitSleepJoinCountCache()
        {
            lock (SyncRoot)
            {
                if (DateTime.Now - LastThreadWaitSleepJoinCountCacheUpdate > ThreadWaitSleepJoinCountUpdateInterval)
                {
                    ;

                    foreach (var thread in threadDict)
                    {
                        if (workerInfoDict[thread.Key].InsideCallBack && thread.Value.ThreadState == ThreadState.WaitSleepJoin)
                            returnValue++;
                    }

                    CurrentNumWaitSleepJoinThreadsCache = returnValue;
                    LastThreadWaitSleepJoinCountCacheUpdate = DateTime.Now;
                }
            }
        }

        /// <summary>
        /// Provides a brief string summarisation the state of the thread pool
        /// 提供了一个简短的字符串解释线程池中的线程的状态
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            lock (SyncRoot)
            {
                UpdateThreadWaitSleepJoinCountCache();
                return "TotalTs:" + CurrentNumTotalThreads.ToString() + ", IdleTs:" + CurrentNumIdleThreads.ToString() + ", SleepTs:" + CurrentNumWaitSleepJoinThreadsCache.ToString() + ", Q:" + QueueCount.ToString();
            }
        }
    }

    /// <summary>
    /// A private wrapper used by CommsThreadPool
    /// 工作者信息类   提供给CommsThreadPool线程池使用
    /// </summary>
    class WorkerInfo
    {
        public int ThreadId { get; private set; }
        public AutoResetEvent ThreadSignal { get; private set; }
        public bool ThreadIdle { get; private set; }
        public DateTime LastActiveTime { get; private set; }
        public WaitCallBackWrapper CurrentCallBackWrapper { get; private set; }
        public bool InsideCallBack { get; private set; }

        public WorkerInfo(int threadId, WaitCallBackWrapper initialisationCallBackWrapper)
        {
            ThreadSignal = new AutoResetEvent(false);
            ThreadIdle = false;
            ThreadId = threadId;
            LastActiveTime = DateTime.Now;
            this.CurrentCallBackWrapper = initialisationCallBackWrapper;
        }

        public void UpdateCurrentCallBackWrapper(WaitCallBackWrapper waitCallBackWrapper)
        {
            CurrentCallBackWrapper = waitCallBackWrapper;
        }

        public void UpdateLastActiveTime()
        {
            LastActiveTime = DateTime.Now;
        }

        public void ClearCallBackWrapper()
        {
            CurrentCallBackWrapper = null;
        }

        /// <summary>
        /// Set InsideCallBack to true
        /// 设置内部回调为True
        /// </summary>
        public void SetInsideCallBack()
        {
            InsideCallBack = true;
        }

        /// <summary>
        /// Set InsideCallBack to false
        /// 设置内部回调为False
        /// </summary>
        public void ClearInsideCallBack()
        {
            InsideCallBack = false;
        }

        /// <summary>
        /// Set threadIdle to true
        /// 设置线程空闲为True
        /// </summary>
        public void SetThreadIdle()
        {
            this.ThreadIdle = true;
        }

        /// <summary>
        /// Set threadIdle to false
        /// 设置线程空闲为False
        /// </summary>
        public void ClearThreadIdle()
        {
            this.ThreadIdle = false;
        }
    }
#endif
    /// <summary>
    /// A private wrapper used by CommsThreadPool
    /// 一个回调的包装器 在自定义线程池中使用
    /// </summary>
    class WaitCallBackWrapper
    {
        public WaitCallback WaitCallBack { get; private set; }
        public object State { get; private set; }

        public WaitCallBackWrapper(WaitCallback waitCallBack, object state)
        {
            this.WaitCallBack = waitCallBack;
            this.State = state;
        }
    }

介绍开源的.net通信框架NetworkComms框架 源码分析(十五 ) CommsThreadPool自定义线程池的更多相关文章

  1. DotNetty网络通信框架学习之源码分析

    DotNetty网络通信框架学习之源码分析 有关DotNetty框架,网上的详细资料不是很多,有不多的几个博友做了简单的介绍,也没有做深入的探究,我也根据源码中提供的demo做一下记录,方便后期查阅. ...

  2. 深入理解分布式调度框架TBSchedule及源码分析

    简介 由于最近工作比较忙,前前后后花了两个月的时间把TBSchedule的源码翻了个底朝天.关于TBSchedule的使用,网上也有很多参考资料,这里不做过多的阐述.本文着重介绍TBSchedule的 ...

  3. 设计模式(十五)——命令模式(Spring框架的JdbcTemplate源码分析)

    1 智能生活项目需求 看一个具体的需求 1) 我们买了一套智能家电,有照明灯.风扇.冰箱.洗衣机,我们只要在手机上安装 app 就可以控制对这些家电工作. 2) 这些智能家电来自不同的厂家,我们不想针 ...

  4. 设计模式(二十一)——解释器模式(Spring 框架中SpelExpressionParser源码分析)

    1 四则运算问题 通过解释器模式来实现四则运算,如计算 a+b-c 的值,具体要求 1) 先输入表达式的形式,比如 a+b+c-d+e,  要求表达式的字母不能重复 2) 在分别输入 a ,b, c, ...

  5. $Django cbv源码分析 djangorestframework框架之APIView源码分析

    1 CBV的源码分析 #视图 class login (View): pass #路由 url(r'^books/$', views.login.as_view()) #阅读源码: #左侧工程栏--- ...

  6. Android源码分析(五)-----如何从架构师的角度去设计Framework框架

    一 : 架构与程序 软件架构是一种思维方式,而程序只是实现思维方式的一种手段,代码固然重要,但是若没有整体的思维架构,一切程序都如水中浮萍. 二 : 框架如何设计 暂时抛开Android Framew ...

  7. NIO框架之MINA源码解析(五):NIO超级陷阱和使用同步IO与MINA通信

    1.NIO超级陷阱 之所以说NIO超级陷阱,就是因为我在本系列开头的那句话,因为使用缺陷导致客户业务系统瘫痪.当然,我对这个问题进行了很深的追踪,包括对MINA源码的深入了解,但其实之所以会出现这个问 ...

  8. ④NuPlayer播放框架之Renderer源码分析

    [时间:2016-11] [状态:Open] [关键词:android,nuplayer,开源播放器,播放框架,渲染器,render] 0 导读 之前我们分析了NuPlayer的实现代码,本文将重点聚 ...

  9. ⑤NuPlayer播放框架之GenericSource源码分析

    [时间:2017-01] [状态:Open] [关键词:android,nuplayer,开源播放器,播放框架,GenericSource] 0 导读 GenericSource是NuPlayer:: ...

随机推荐

  1. java 泛型思考

    java泛型并没有像C++那样原生支持,因此,为了保证迁移兼容性,编译器在编译时会擦除具体类型,因此不能通过泛型调用具体方法. 如果调用必须用extends关键字限定范围,也正是由于这个原因,java ...

  2. C#中动态读写App.config配置文件

    转自:http://blog.csdn.net/taoyinzhou/article/details/1906996 app.config 修改后,如果使用cofnigurationManager立即 ...

  3. linux服务之maven

    curl -O http://mirrors.noc.im/apache/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.zip [root@d ...

  4. STM32F4 SPI2初始化及收发数据【使用库函数】

    我的STM32F4 Discovery上边有一个加速度传感器LIS302DL.在演示工程中,ST的工程师使用这个传感器做了个很令人羡慕的东西:解算开发板的姿态.当开发板倾斜时候,处于最上边的LED点亮 ...

  5. 封装实现一个自己的tabbar

    实现效果:

  6. RMAN_学习笔记2_RMAN Setup配置和监控

    2014-12-23 Created By BaoXinjian

  7. python(23)re函数:compile、match、search、findall

    正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配. Python 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式. re 模块使 Python ...

  8. FreeBSD 10 中文环境

    中文字体位置 FontPath        "/usr/local/lib/X11/fonts/misc/:unscaled" FontPath        "/us ...

  9. 高亮代码显示之HTML困惑

    近期做样式库,需要将HTML代码高亮,开始寻找相关的插件. 看到highlight.js,看到它主题样式如此之多,支持语言也如此之多,以为找到了神器.不想这只是痛苦的开始,为了让它支持HTML,我尝试 ...

  10. windows下PHP5.5.6+Apache2.4.7配置

    本文主要阐述在windows8及win8.1 环境下搭建PHP5.5.6+Apache2.4.7. 1.软件准备 apache 2.4.7:http://pan.baidu.com/s/1iUPif ...