void ActivateWorkerThread(WorkerThread workerThread, WorkItem workItem) { workerThread.SetWork(workItem.Execute); workerThread.Complete += this.WorkComplete; workerThread.Activate(); }
/// <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); } }