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;
        }
예제 #3
0
 private void ExecuteJob(ThreadPoolWorkItem job)
 {
     try
     {
         job.Execute();
     }
     catch (Exception e)
     {
         OnWorkItemException(job, e);
     }
     finally
     {
         Interlocked.Decrement(ref _taskCount);
     }
 }
예제 #4
0
 private void OnWorkItemException(ThreadPoolWorkItem job, Exception e)
 {
     if (WorkItemExceptionHandler != null)
     {
         WorkItemExceptionHandler(this, new WorkItemEventArgs()
         {
             Exception = e,
             UserData = job == null ? null : job.UserData,
         });
     }
 }
예제 #5
0
        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;
            }
        }