public void Ready()
        {
            if (_subscription == null)
            {
                throw new Exception("Subscription not initialized, call Init first");
            }
            if (PriorityQueue == null)
            {
                throw new Exception("PriorityQueue not initialized, call Init first");
            }

            lock (SyncRoot)
            {
                _pool = new SafeSemaphore(_watcher, _batchSize, _batchSize, _sharedSemaphore);
            }

            Task.Factory.StartNew(() =>
            {
                try
                {
                    Thread.CurrentThread.Name = string.Format("Consumer thread: {0}, Priority queue: {1}", ConsumerTag, _queuePriorirty);
                    while (!_disposed && !_channelShutdown)
                    {
                        try
                        {
#if DEBUG
                            _watcher.DebugFormat("1. Wait the semaphore to release");
                            _pool.WaitOne();
                            _watcher.DebugFormat("2. Semaphore released, wait a msg from RabbitMQ. Probably a wait-for-ack message is blocking this");
#else
                            _pool.WaitOne();
#endif
                            var msg = PriorityQueue.Dequeue();
                            
                            if (msg != null && msg.Message != null)
                            {
#if DEBUG
                                _watcher.DebugFormat("3. Msg from RabbitMQ arrived (probably the previous msg has been acknownledged), prepare to handle it");

#endif
                                HandleMessageDelivery(msg.Message);
                            }
                            else
                            {
                                _watcher.ErrorFormat("Msg from RabbitMQ arrived but it's NULL for some reason, properly a serious BUG :D, contact author asap, release the semaphore for other messages");
                                _pool.Release();
                            }
                        }
                        catch (EndOfStreamException) // NOTE: Must keep the consumer thread alive
                        {
                            // This happen when the internal Queue is closed. The root reason could be connection problem
                            Thread.Sleep(100);
#if DEBUG                            
                            _watcher.DebugFormat("EndOfStreamException occurs, release the semaphore for another message");

#endif
                            _pool.Release();
                        }
                        catch (BadMessageHandlerException ex)
                        {
                            _watcher.Error(ex);
                            Dispose();
                        }
                    }
                }
                catch (ThreadStateException tse)
                {
                    _watcher.WarnFormat("The consumer thread {0} on queue {1} got a ThreadStateException: {2}, {3}", ConsumerTag, _queuePriorirty, tse.Message, tse.StackTrace);
                }
                catch(ThreadInterruptedException)
                {
                    _watcher.WarnFormat("The consumer thread {0} on queue {1} is interrupted", ConsumerTag, _queuePriorirty);
                }
                catch (ThreadAbortException)
                {
                    _watcher.WarnFormat("The consumer thread {0} on queue {1} is aborted", ConsumerTag, _queuePriorirty);
                }
            }, TaskCreationOptions.LongRunning);
        }