public override bool QueueUserWorkItem(Action<CancellationToken, object> target, object userData) { //User signaled to stop all processing so return false and dont add any new work items. if (_poolStopToken.IsCancellationRequested) return false; var job = new ThreadPoolWorkItem(target, userData, _poolStopToken); while (true) { //var w = SelectMinLoadRandomNode(); var w = SelectRoundRobinNode(); if (w.TaskCount != 0 && _workerKeys.Count < _settings.MaxThreads ) { lock (_lock) { //new threads are needed. check if pool have capacity and add them now. if (_workerKeys.Count < _settings.MaxThreads) { w = AllocDelegate(); _workerThreads.TryAdd(w.Name, w); _workerKeys.Add(w.Name); } } } if (w.Status == PoolWorkerStatus.Running) { w.EnqueueWorkItem(job); EtwLogger.Log.PoolWorkerSelected(w.Name, w.TaskCount); //Console.WriteLine("Assigned to worker: {0}", w.Name); return true; } else { EtwLogger.Log.PoolWorkerAssignmentFailed(w.Name, w.TaskCount); //Console.WriteLine("failed to assign to worker: {0}", w.Name); } } }
/// <summary> /// Enqueues new work to be executed in thread pool. /// </summary> /// <param name="target">delegate which will execute the work item on thread pool thread</param> /// <param name="userData">any user data needed by the delegate</param> /// <returns>true if work item is enqueued, false otherwise</returns> public override bool QueueUserWorkItem(Action<System.Threading.CancellationToken, object> target, object userData) { if (_poolStopToken.IsCancellationRequested) return false; if (target == null) throw new ArgumentNullException("target"); var work = new ThreadPoolWorkItem(target, userData, _poolStopToken); // If execution context flowing is on, capture the caller’s context. if (_settings.EnableExecutionContext) work.ExecutionCtx = ExecutionContext.Capture(); // Now insert the work item into the queue, possibly waking a thread. ThreadLocalStealQueue<ThreadPoolWorkItem> wsq = _mWsq; if (wsq != null) { // Single TLS to determine this execution is on a pool thread. wsq.LocalPush(work); if (wsq.Count > _settings.MinThreads) { EnsureThreadCapacity(); } } else { //put item in global queue because this is being added from user's thread lock (_mQueue) { _mQueue.Enqueue(work); if (_mQueue.Count > _settings.MinThreads) { // Make sure the pool is running with optimal number of required threads. EnsureThreadCapacity(); } } } return true; }
private void ExecuteJob(ThreadPoolWorkItem job) { try { job.Execute(); } catch (Exception e) { OnWorkItemException(job, e); } finally { Interlocked.Decrement(ref _taskCount); } }
private void OnWorkItemException(ThreadPoolWorkItem job, Exception e) { if (WorkItemExceptionHandler != null) { WorkItemExceptionHandler(this, new WorkItemEventArgs() { Exception = e, UserData = job == null ? null : job.UserData, }); } }
public bool EnqueueWorkItem(ThreadPoolWorkItem item) { lock (_queue) { if (_status != PoolWorkerStatus.Running) { //make sure to initialize the thread. return false; } _queue.Add(item); Interlocked.Increment(ref _taskCount); return true; } }