EventingBasicConsumer Listener with out while loop

2,065 views
Skip to first unread message

Kengie Ho

unread,
May 18, 2017, 4:19:11 PM5/18/17
to rabbitmq-users
Hi there,

I am trying to use the EventBasicConsumer listener to pick up any messages that are in the queue.  But on the RabbitMQ site sample code, they have a Console.Readline() to hold/pause the execution at the channel.BasicConsume code.

The problem is that I am writing a Windows Services App and Console.ReadLine() doesn't hold the BasicConsume operation and I need to use  a while(true) loop to constantly ping the queue for new messages.  This causes a high load on the CPU and I kinda was to have a push message from the exchange to the consumer.  I have search up on google and I can't find an example code with out a while loop. During my test the BasicConsume would pull only one message from the queue and then it would run to completion and exit the method (cause that the is last line of code, which is BasicConsume).  I have also try to wrap the BasicConsume statement in a new task and pull one message and doesn't execute again while there is more message in the queue or while more messages are added to the queue.

Is there a way to for the BasicConsume to keep executing without a while loop?  Many thanks.

My Specs:
RabbitMQ.Client 3.6.9 (because I'm using .Net Framework 4.5)
RabbitMQ Server 3.6.9 with Erlang 19.3 on Windows Server


Below is my sample Code:
            using (var connection = factory.CreateConnection())
            using (var channel = connection.CreateModel())
            {
                // Basic Properties for RabbitMQ
                IBasicProperties properties = channel.CreateBasicProperties();
                properties.Persistent = true;
                channel.ExchangeDeclare(exchange: "MyExchange", type: "direct", durable: true);
                channel.QueueDeclare(queue: "MyQueue", durable: true, exclusive: false, autoDelete: false, arguments: null);
                channel.QueueBind(queue: "MyQueue", exchange: "MyExchange", routingKey: string.Empty);
                channel.BasicQos(prefetchSize: 0, prefetchCount: 1, global: false);
                #region "EventingBasicConsumer - Kept for reference"
                //Console.WriteLine(" [*] Waiting for messages.");
                // Declare the Event Handler to process logic
                var consumer = new EventingBasicConsumer(channel);
                consumer.Received += (model, ea) =>
                {
                    var body = ea.Body;
                   
                    // Do Some Processing
                    channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
                };
                channel.BasicConsume(queue: "MyQueue",
                                     noAck: false,
                                     consumer: consumer);
            }


Many thanks for your help.


Kengie





Michael Klishin

unread,
May 18, 2017, 9:01:02 PM5/18/17
to rabbitm...@googlegroups.com
With basic.consume and EventingBasicConsumer you absolutely do not have to use a while loop
(in fact, none of our tutorials do).

A loop may be used in code examples to keep the program alive but EventingBasicConsumer,
as the name suggests, is all about dispatching events.

There are no loops used in our tutorials, for example:

--
You received this message because you are subscribed to the Google Groups "rabbitmq-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rabbitmq-users+unsubscribe@googlegroups.com.
To post to this group, send email to rabbitmq-users@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
MK

Staff Software Engineer, Pivotal/RabbitMQ

Kengie Ho

unread,
May 18, 2017, 10:55:47 PM5/18/17
to rabbitm...@googlegroups.com
Thank you for your reply. 

The tutorial example uses the Console.Readline() to hold the thread active.  In a Windows Service App, the Console.Readline() doesn't work or hold the thread active. 

As in my attached code, when the execution code would called BasicConsume and pull one message from the queue and exit the method as the BasicConsume statement is the last statement in the method and it would just exit the method as there is no statement to keep the thread alive.  I have also tried to wrap the BasicConsume statement in a new Threading Task but it would only execute one message off the queue.

So I was wondering if there is any sample code for EventingBasicConsume that is in a Windows Service sample instead of Console sample. 

Thanks. 

Kengie


To unsubscribe from this group and stop receiving emails from it, send an email to rabbitmq-user...@googlegroups.com.

To post to this group, send email to rabbitm...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
MK

Staff Software Engineer, Pivotal/RabbitMQ

--
You received this message because you are subscribed to a topic in the Google Groups "rabbitmq-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/rabbitmq-users/76nVbHBPBlU/unsubscribe.
To unsubscribe from this group and all its topics, send an email to rabbitmq-user...@googlegroups.com.
To post to this group, send email to rabbitm...@googlegroups.com.

Michael Klishin

unread,
May 19, 2017, 3:26:54 AM5/19/17
to rabbitm...@googlegroups.com
The question comes down roughly to "how do I keep .NET app that only uses background threads from stopping".
There should be nothing RabbitMQ or RabbitMQ .NET client-specific in that ;)

To unsubscribe from this group and stop receiving emails from it, send an email to rabbitmq-users+unsubscribe@googlegroups.com.

To post to this group, send email to rabbitmq-users@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
MK

Staff Software Engineer, Pivotal/RabbitMQ

--
You received this message because you are subscribed to a topic in the Google Groups "rabbitmq-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/rabbitmq-users/76nVbHBPBlU/unsubscribe.
To unsubscribe from this group and all its topics, send an email to rabbitmq-users+unsubscribe@googlegroups.com.
To post to this group, send email to rabbitmq-users@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "rabbitmq-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rabbitmq-users+unsubscribe@googlegroups.com.
To post to this group, send email to rabbitmq-users@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Karl Nilsson

unread,
May 19, 2017, 4:38:18 AM5/19/17
to rabbitm...@googlegroups.com
Don't dispose of your connection and channel if you want to maintain your connection for the lifetime of the application.


To post to this group, send email to rabbitm...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
MK

Staff Software Engineer, Pivotal/RabbitMQ

--
You received this message because you are subscribed to a topic in the Google Groups "rabbitmq-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/rabbitmq-users/76nVbHBPBlU/unsubscribe.
To unsubscribe from this group and all its topics, send an email to rabbitmq-users+unsubscribe@googlegroups.com.

To post to this group, send email to rabbitm...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "rabbitmq-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rabbitmq-users+unsubscribe@googlegroups.com.
To post to this group, send email to rabbitm...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
MK

Staff Software Engineer, Pivotal/RabbitMQ

--
You received this message because you are subscribed to the Google Groups "rabbitmq-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rabbitmq-users+unsubscribe@googlegroups.com.
To post to this group, send email to rabbitmq-users@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Karl Nilsson

Pivotal/RabbitMQ

Kengie Ho

unread,
May 19, 2017, 8:25:33 AM5/19/17
to rabbitm...@googlegroups.com
Thank you Michael and Karl.

Mich, yeah.  You are right on that part. It is more of a RabbitMQ .Net client-specific question.  I will research it some more and see what I can come up with.

Karl, on the topic of  connection and channels.  I found that on client 3.6.9, whenever I call channel.BasicPublish.  The client would create a connection (I check under the management UI of the Rabbit MQ) and the connection would stay persistent until the application is closed.  So if I have a loop of X items, the connections would be X connections.  The only way I was able to remedy this was to create a connection and channel, then close both of them for each item/message that I would like to send to the queue.  But there then there is the efficiency of the setup and teardown of the connection and channels.  I was wondering if there is a connection pool or a single connection to enqueue all my X amount of messages to be queued.

Many thanks for your time.

Kengie

Virus-free. www.avast.com

Karl Nilsson

Pivotal/RabbitMQ

--
You received this message because you are subscribed to a topic in the Google Groups "rabbitmq-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/rabbitmq-users/76nVbHBPBlU/unsubscribe.
To unsubscribe from this group and all its topics, send an email to rabbitmq-users+unsubscribe@googlegroups.com.

Kengie Ho

unread,
May 19, 2017, 11:26:24 AM5/19/17
to rabbitm...@googlegroups.com
So to return back to the community, I have found the workaround replacement for the Console.ReadLine() if you are trying to convert to Windows Services.

In order to keep the thread alive at the BasicConsume line when using EventingBasicConsume.  You can use the statement:

System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite) right after the BasicConsume statement.

Kengie

Herbey Zepeda

unread,
Sep 23, 2017, 4:13:58 PM9/23/17
to rabbitmq-users
Michael Klishin,

You are right, my concern with EventingBasicConsumer is that, according to your website, is still considered "experimental" and that is subject to change at any time. 

What is the next best alternative at this point to have a consumer constantly reading at a queue in a windows services other than having a while loop and not having to use an "experimental" module?


ref.


Thank you

To unsubscribe from this group and stop receiving emails from it, send an email to rabbitmq-user...@googlegroups.com.
To post to this group, send email to rabbitm...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Michael Klishin

unread,
Sep 24, 2017, 6:21:30 AM9/24/17
to rabbitm...@googlegroups.com
Please take a look at the URL you’ve linked to.
You are looking at the 1.4.0 version of the client which was released in July 2008

Man, we really gotta remove some of those docs.

EventingBasicConsumer is used by our tutorials, which should also suggest it’s beyond a certain maturity point.

Michael Klishin

unread,
Sep 24, 2017, 6:28:13 AM9/24/17
to rabbitm...@googlegroups.com
I deleted .NET client 1.x and 2.x docs. There is no reason to not use at least a 3.x
version (even if you are on a truly ancient .NET version such as 1.1!) and those
old references do more harm than good at this point.

Herbey Zepeda

unread,
Sep 24, 2017, 9:23:41 PM9/24/17
to rabbitmq-users
Got it,thanks!
Reply all
Reply to author
Forward
0 new messages