I have been doing a small sample application to consume messages on a queue in RabbitMQ.
The code should read the message an call a REST API (here replaced with a Task.Delay):
static void Main(string[] args)
{
var factory = new ConnectionFactory
{
Uri = new Uri("..."),
DispatchConsumersAsync = true
};
var connection = factory.CreateConnection();
var channel = connection.CreateModel();
var consumer = new AsyncEventingBasicConsumer(channel);
consumer.Received += async (model, eventArgs) =>
{
Console.WriteLine("Doing a fake API call...");
await Task.Delay(2000);
Console.WriteLine("Done with fake API call!");
channel.BasicAck(eventArgs.DeliveryTag, false);
};
channel.BasicConsume("myQueue", false, consumer);
}
When I run this application with five messages on the queue I get the following result:

The messages are processed one by one and with the 2 second delay it takes ~10 seconds.
I would have expected to see five lines with Doing a fake API call... followed by five lines of Done with fake API call! with a total time of ~2 seconds.
When doing the synchronous version I see the exact same result - which was expected:
static void Main(string[] args)
{
var factory = new ConnectionFactory
{
Uri = new Uri("...")
};
var connection = factory.CreateConnection();
var channel = connection.CreateModel();
var consumer = new EventingBasicConsumer(channel);
consumer.Received += (model, eventArgs) =>
{
Console.WriteLine("Doing a fake API call...");
Thread.Sleep(2000);
Console.WriteLine("Done with fake API call!");
channel.BasicAck(eventArgs.DeliveryTag, false);
};
channel.BasicConsume("myQueue", false, consumer);
}
My question is: What is the difference in using the AsyncEventingBasicConsumer compared to the EventingBasicConsumer?
And: Is there a way of making the consumer process other messages while awaiting work for previous messages?