Esempio n. 1
0
 void ActivateWorkerThread(WorkerThread workerThread, WorkItem workItem)
 {
     workerThread.SetWork(workItem.Execute);
     workerThread.Complete += this.WorkComplete;
     workerThread.Activate();
 }
Esempio n. 2
0
        /// <summary>
        /// 该方法必须在 locked 下执行
        /// </summary>
        /// <param name="workerThread"></param>
        /// <param name="workItem"></param>
        /// <param name="workerThreadCall">是否是当前池内的线程调用该方法</param>
        /// <returns></returns>
        bool TryGetWorkerThreadAndWorkItem(out WorkerThread workerThread, out WorkItem workItem, bool workerThreadCall)
        {
            workerThread = null;
            workItem     = null;

            if (this._workQueue.Count > 0)
            {
                if (this._freeTreads.Count > 0)
                {
                    workerThread = this._freeTreads.Dequeue();
                    workItem     = this._workQueue.Dequeue();
                    this._workingTreads.Add(workerThread);

                    return(true);
                }
                else
                {
                    if (this._allThreads.Count < this._threads)
                    {
                        workerThread = new WorkerThread();
                        workItem     = this._workQueue.Dequeue();
                        this._allThreads.Add(workerThread);
                        this._workingTreads.Add(workerThread);

                        return(true);
                    }
                    return(false);
                }
            }
            else
            {
                if (!workerThreadCall)
                {
                    return(false);
                }

                double t = this._keepAliveTime;
                if (t < 0)
                {
                    this._workQueue.TrimExcess();
                    return(false);
                }

                //此代码块只有当前池内的线程完成工作了以后访问到,从 QueueWorkItem 方法调用该方法是不会执行此代码块的,因为 this.workQueue.Count > 0
                if (this._freeTreads.Count == this._allThreads.Count && this._workingTreads.Count == 0 && this._freeTreads.Count > 0)
                {
                    /*
                     *能执行到这,说明池内没有了任何任务,并且是最后一个活动线程执行完毕
                     * 此时从池中取出一个线程来执行 Tick 方法
                     */
                    DateTime now      = DateTime.Now;
                    int      threadId = Thread.CurrentThread.ManagedThreadId;
                    if (this._allThreads.Any(a => a.ThreadId == threadId)) //既然只有当前池内的线程能访问到这,这句判断是不是有点多余了- -
                    {
                        workerThread = this._freeTreads.Dequeue();         //弹出一个 WorkerThread 对象,此时不需将弹出的 WorkerThread 对象放入 workingTreads 队列中,因为该对象是供池内自身计时用,相对外界是不知道的,保证外界调用 GetAvailableThreads 方法能得到一个合理的结果
                        workItem     = new WorkItem((state) =>
                        {
                            this.Tick((WorkerThread)state);
                        }, workerThread);

                        this._spin = true;
                        try
                        {
                            this._releaseTime = now.AddMilliseconds(t);//设置待释放线程的时间点
                        }
                        catch (ArgumentOutOfRangeException)
                        {
                            this._releaseTime = DateTime.MaxValue;
                        }

                        return(true);
                    }
                }

                return(false);
            }
        }