protected void ProcessQueue() { try { while (_run) { // Update time this thread was last alive _threads[Thread.CurrentThread] = DateTime.Now; // Check if increase of number of threads is desired CheckThreadIncrementRequired(); // Wait until we receive a work item IWork work = _workQueue.Dequeue(_startInfo.ThreadIdleTimeout, _cancelWaitHandle); if (work == null) { // Dequeue has returned null or we should shutdown if (_threads.Count > _startInfo.MinimumThreads) { lock (_syncObj) { if (_threads.Count > _startInfo.MinimumThreads) { ServiceRegistration.Get <ILogger>().Debug("ThreadPool.ProcessQueue(): Quitting (inUse: {0}, total: {1})", _inUseThreads, _threads.Count); // remove thread from the pool if (_threads.ContainsKey(Thread.CurrentThread)) { DateTime time; _threads.TryRemove(Thread.CurrentThread, out time); } break; } } } CheckForIntervalBasedWork(); // Skip this iteration if we got here and work is null continue; } // ServiceRegistration.Get<ILogger>().Debug("ThreadPool.ProcessQueue(): Received valid work: {1}", work.State); try { // Only process items which have status INQUEUE (don't process CANCEL'ed items) if (work.State == WorkState.INQUEUE) { Thread.CurrentThread.Priority = work.ThreadPriority; IncInUseThreadCount(); // ServiceRegistration.Get<ILogger>().Debug("ThreadPool.ProcessQueue(): Processing work {1}", work.Description); work.Process(); // ServiceRegistration.Get<ILogger>().Debug("ThreadPool.ProcessQueue(): Finished processing work {0}", work.Description); } } catch (Exception e) { ServiceRegistration.Get <ILogger>().Warn("ThreadPool.ProcessQueue(): Exception during processing work '{0}'", e, work.Description); work.State = WorkState.ERROR; work.Exception = e; } finally { if (work.State == WorkState.FINISHED || work.State == WorkState.ERROR) { Interlocked.Increment(ref _itemsProcessed); // ServiceRegistration.Get<ILogger>().Debug("ThreadPool.ProcessQueue(): {0} items processed", _itemsProcessed); DecInUseThreadCount(); // ServiceRegistration.Get<ILogger>().Debug("ThreadPool.ProcessQueue(): Finished processing work {0}", work.Description); } Thread.CurrentThread.Priority = _startInfo.DefaultThreadPriority; } CheckForIntervalBasedWork(); } } catch (ThreadAbortException) { ServiceRegistration.Get <ILogger>().Debug("ThreadPool.ProcessQueue(): Thread aborted"); Thread.ResetAbort(); } catch (Exception e) { ServiceRegistration.Get <ILogger>().Error("ThreadPool.ProcessQueue(): Error executing work", e); } finally { if (_threads.ContainsKey(Thread.CurrentThread)) { DateTime time; _threads.TryRemove(Thread.CurrentThread, out time); } } }