title: How to implement subscribe model for RabbitMQ and requeue unprocessed messages
body: <p>I have a Windows service that consumes messages from a remotely hosted RabbitMQ queue.</p>
  
  <p>I have working code that wakes up at fixed intervals and connects to the queue and takes messages and processes them (mostly persists them to a database). This is a simplified version of what works for me:</p>
  
  <pre><code>        #region currentmethod
  
          IConnection connection = factory.CreateConnection();
          IModel channel = connection.CreateModel();
          channel.ExchangeDeclare(EXCHANGE_NAME, ExchangeType.Direct, true, false, null);
          QueueDeclareOk queueDeclareOK = channel.QueueDeclare(queue: queueName, durable: true, exclusive: false, autoDelete: true, arguments: null);
          channel.QueueBind(queue: queueName, exchange: EXCHANGE_NAME, routingKey: routingkey);
  
          Console.WriteLine(queueDeclareOK.MessageCount.ToString());
  
          BasicGetResult result = channel.BasicGet(queueName, false);
          byte[] body = result.Body;
          string message = Encoding.UTF8.GetString(body);
          if (ProcessData(message))
              channel.BasicAck(result.DeliveryTag, false);
          else
              channel.BasicNack(result.DeliveryTag, false, true);
  
          channel.Close(200, "goodbye");
          connection.Close();
          #endregion currentmethod
  </code></pre>
  
  <p>What I would like to do is implement the publish-subscribe model as described <a href="https://www.rabbitmq.com/tutorials/tutorial-three-dotnet.html" rel="nofollow noreferrer">https://www.rabbitmq.com/tutorials/tutorial-three-dotnet.html</a> so that as messages enter the queue the subscriber processes them immediately. What I need to ensure is that if the message is not successfully processed it remains in the queue and is not lost.</p>
  
  <p>Here is code basically along these lines:</p>
  
  <pre><code>        #region subscribeModel
          using (connection = factory.CreateConnection())
          {
              using (channel = connection.CreateModel())
              {
                  channel.ExchangeDeclare(EXCHANGE_NAME, ExchangeType.Direct, true, false, null);
                  channel.QueueDeclare(queue: queueName, durable: true, exclusive: false, autoDelete: true, arguments: null);  
                  channel.QueueBind(queueName, EXCHANGE_NAME, routingKey);
  
                  EventingBasicConsumer consumer = new EventingBasicConsumer(channel);
                  consumer.Received += (o, e) =&gt;
                      {
                          string data = Encoding.ASCII.GetString(e.Body);
                          Console.WriteLine(data);                           
                      };
  
                  string consumerTag = channel.BasicConsume(queueName, false, consumer);                 
  
                  Console.WriteLine("Listening, press ENTER to quit");
                  Console.ReadLine();                                        
              }
          }
  
          #endregion subscribeModel
  </code></pre>
  
  <p>I have three difficulties with this.</p>
  
  <ol>
  <li><p>After messages are read they are in the Unacked state but I need them to return to the Ready state. If they are successfully processed they should be Acked and leave the queue but if the processing fails they must remain in the queue.</p></li>
  <li><p>I need to do something other than write the data to the console, but where do I put the Process code in this model? </p></li>
  <li><p>When my code terminates in the subscription model, the queue that I have connected to is deleted, losing any messages that are in it in any state.</p></li>
  </ol>
  
  <p>Does anyone know how I can requeue un-processed messages and prevent the queue from being deleted if my consumer closes?</p>