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); }