10
while (true)
{
    BasicDeliverEventArgs e = (BasicDeliverEventArgs)Consumer.Queue.Dequeue();
    IBasicProperties properties = e.BasicProperties;
    byte[] body = e.Body;
    Console.WriteLine("Recieved Message : " + Encoding.UTF8.GetString(body));
    ch.BasicAck(e.DeliveryTag, false);
}

This is what we do when we Retrieve Message by subscription..We use While Loop because we want Consumer to listen Continously..what if i want to make this even based..that is when a new message arrives in the queue at that time only Consumer should Consume the message..or on any such similar event..

Phil H
  • 19,928
  • 7
  • 68
  • 105
Jigar Sheth
  • 586
  • 2
  • 5
  • 21
  • 1
    Can you use the EventingBasicConsumer? http://www.java2s.com/Open-Source/CSharp/Message/RabbitMQ/RabbitMQ/Client/Events/EventingBasicConsumer.cs.htm – maxfridbe Nov 30 '11 at 16:33
  • 1
    See also: http://stackoverflow.com/questions/12499174/rabbitmq-c-sharp-driver-stops-receiving-messages – Babak Sep 21 '14 at 11:45

3 Answers3

9

use the RabbitMQ.Client.Events.EventingBasicConsumer for a eventing consumer instead of a blocking one.

Carl Hörberg
  • 5,973
  • 5
  • 41
  • 47
  • 3
    Please note that [EventingBasicConsumer](http://www.rabbitmq.com/releases/rabbitmq-dotnet-client/v2.8.1/rabbitmq-dotnet-client-2.8.1-client-htmldoc/html/type-RabbitMQ.Client.Events.EventingBasicConsumer.html) is currently listed as experimental. – WhiteKnight Apr 27 '12 at 20:51
  • I have a full example on my website of how to do this in C#. http://www.jarloo.com/listening-to-rabbitmq-events/ – Kelly May 24 '12 at 20:21
7

You're currently blocking on the Consumer.Queue.Dequeue(). If I understand your question correctly, you want to asynchronously consume messages.

The standard way of doing this would be to write your own IBasicConsumer (probably by subclassing DefaultBasicConsumer) and set it as the consumer for the channel.

The trouble with this is that you have to be very careful about what you do in IBasicConsumer.HandleBasicDelivery. If you use any synchronous AMQP methods, such as basic.publish, you'll get a dead-lock. If you do anything that takes a long time, you'll run into some other problems.

If you do need synchronous methods or long-running actions, what you're doing is about the right way to do it. Have a look at Subscription; it's an IBasicConsumer that consumes messages and puts them on a queue for you.

If you need any more help, a great place to ask is the rabbitmq-discuss mailing list.

scvalex
  • 14,931
  • 2
  • 34
  • 43
  • 5
    summary: don't share IModel betweenthreads. it's quite cheap to create new connections/models (compared to the cost for debugging concurrency bugs). – Carl Hörberg Dec 14 '10 at 21:00
  • According to .net client user guide application handlers can call IModel.BasicPublish without resulting in deadlock because they are async operations. But calling QueueDeclare or BasicCancel from handlers will result in deadlock. – maulik13 Mar 11 '15 at 08:37
4

I had this problem and could not find an answer so created a demonstration project to have the RabbitMQ subscription raise .Net events when a message is received. The subscription runs on its own thread leaving the UI (in mycase) free to do it thing.

I amusing call my project RabbitEar as it listens out for messages from the mighty RabbitMQ I intend to share this with the RabbitMQ site so if they think its of value they can include a link / code in there examples.

Check it out at http://rabbitears.codeplex.com/

Thanks Simon

Simon Thompson
  • 708
  • 6
  • 14