Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Explain AsyncEventingBasicConsumer behaviour without DispatchConsumersAsync = true

I am trying out the RabbitMQ AsyncEventingBasicConsumer using the following code:

static void Main(string[] args)
{
    Console.Title = "Consumer";

    var factory = new ConnectionFactory() { DispatchConsumersAsync = true };
    const string queueName = "myqueue";

    using (var connection = factory.CreateConnection())
    using (var channel = connection.CreateModel())
    {
        channel.QueueDeclare(queueName, true, false, false, null);

        // consumer

        var consumer = new AsyncEventingBasicConsumer(channel);
        consumer.Received += Consumer_Received;
        channel.BasicConsume(queueName, true, consumer);

        // publisher

        var props = channel.CreateBasicProperties();
        int i = 0;

        while (true)
        {
            var messageBody = Encoding.UTF8.GetBytes($"Message {++i}");
            channel.BasicPublish("", queueName, props, messageBody);
            Thread.Sleep(50);
        }
    }
}

private static async Task Consumer_Received(object sender, BasicDeliverEventArgs @event)
{
    var message = Encoding.UTF8.GetString(@event.Body);

    Console.WriteLine($"Begin processing {message}");

    await Task.Delay(250);

    Console.WriteLine($"End processing {message}");
}

It works as expected. If I don't set the DispatchConsumersAsync property, however, the messages get consumed but the event handler never fires.

I find it hard to believe that this dangerous behaviour (losing messages because a developer forgot to set a property) is by design.

Questions:

  1. What does DispatchConsumersAsync actually do?
  2. What is happening under the hood in the case without DispatchConsumersAsync, where consumption is taking place but the event handler does not fire?
  3. Is this behaviour by design?
like image 361
Gigi Avatar asked Aug 31 '25 18:08

Gigi


1 Answers

The answer actually in your question. Yes, it is about design. The documentation explains and gives small example about async pattern.

The client provides an async-oriented consumer dispatch implementation. This dispatcher can only be used with async consumers, that is, IAsyncBasicConsumer implementations.
In order to use this dispatcher, set the ConnectionFactory.DispatchConsumersAsync property to true

So documentation has not enough information to answer your first question. However for second, if you want to use AsyncEventingBasicConsumer, you must to set ConnectionFactory.DispatchConsumersAsync property to true. It is design and rule of RabbitMq.
Also third question actually you answer yourself. Yes, for now it is about design of RabbitMq .net client.

like image 77
is_oz Avatar answered Sep 02 '25 09:09

is_oz