public IThreadTaskInfo QueueUserWorkItem(WaitCallback callback, object state)
        {
            if (_cancelTS.IsCancellationRequested)
            {
                throw new ApplicationException("This thread pool is not running and cannot be used.");
            }

            ThreadTaskInfo item = new ThreadTaskInfo(callback, state)
            {
                TaskStatus = TaskStatus.WaitingToRun
            };

            _queue.Add(item);

            return(item);
        }
        private void ProcessQueue()
        {
            while (!_cancelTS.IsCancellationRequested)
            {
                ThreadTaskInfo taskInfo = null;

                try
                {
                    //blocks til a task is available
                    taskInfo = _queue.Take(_cancelTS.Token);
                }
                catch (OperationCanceledException)
                {
                    //Take was cancelled, stop processing tasks
                    break;
                }

                if (taskInfo != null)
                {
                    try
                    {
                        Interlocked.Increment(ref _activeThreadCount);
                        taskInfo.TaskStatus = TaskStatus.Running;
                        taskInfo.Callback(taskInfo.State);
                        taskInfo.TaskStatus = TaskStatus.RanToCompletion;
                    }
                    catch (Exception ex)
                    {
                        taskInfo.TaskStatus = TaskStatus.Faulted;
                    }
                    finally
                    {
                        Interlocked.Decrement(ref _activeThreadCount);
                    }
                }
            }
        }