private void ThreadProc()
        {
            try
            {
                while (_isRunning)
                {
                    //---- Wait until we wake up this thread
                    if (_commandsCount < 1)
                    {
                        //-- Wait...
                        bool hasTimeOut = false;
                        lock (this)
                            hasTimeOut = !Monitor.Wait(this, _uselessThreadTimeout);

                        //-- The thread pool is NOT heavily used, remove this thread from the pool
                        if (hasTimeOut)
                        {
                            lock (_threads)

                                if (_threads.Count > _minThreadsCount)
                                {
                                    _threads.Remove(Thread.CurrentThread);
                                    return;
                                }
                            continue;
                        }
                    }

                    //---- Process at least one command, if fast enough can process several commands
                    Interlocked.Increment(ref _busyThreads);

                    //---- Thread pool is heavily used, add a thread to the pool
                    if (_busyThreads == _threads.Count)
                    {
                        AddThreadToPool();
                    }

                    ProcessAllCommands();
                    Interlocked.Decrement(ref _busyThreads);
                }
            }

            catch (ThreadAbortException)
            {
            }

            catch (Exception exception)
            {
                ExceptionsHandler.Handle(exception);
            }
        }
        /// <summary>
        /// To avoid too much context switching, we try to processing several commands.
        /// But this thread cannot execute during too much time.
        /// </summary>
        private void ProcessAllCommands()
        {
            while (_isRunning)
            {
                //---- Get the next command
                ICommand command;

                if (!_commands.TryDequeue(out command))
                {
                    return;                     // No more commands
                }
                Interlocked.Decrement(ref _commandsCount);

                //---- Execute the command
                try
                {
                    command.Execute();
                }

                catch (Exception exception)
                {
                    ExceptionsHandler.Handle(exception);
                    //Console.WriteLine(exception.Message);
                }

                // Statistics
                Interlocked.Increment(ref _totalExecutedCommands);

                /*
                 *
                 *                              // Process commands since more than 20 ms, allows context switching
                 *                              if (HighResClock.TicksToMs(HighResClock.NowTicks - ticks) > ThreadHelper.ThreadMaxExecutionTime)
                 *                              {
                 *                                      ThreadHelper.StallThread();
                 *                                      return;
                 *                              }*/
            }
        }