7

Is there a way to receive multiple message using a single synchronous call using .NET?
I've seen question and I've found java class com.rabbitmq.client.QueueingConsumer, but I haven't found such client class in .NET namespaces (RabbitMQ.Client, RabbitMQ.Client.Events)

3
  • Could you please describe more about what you mean by "a single synchronous call?" Commented Aug 31, 2015 at 12:23
  • Well, more correct: I want to receive one event with batch of messages (configuring client to max batch size and timeout). Hope this explanation is more clear Commented Aug 31, 2015 at 13:06
  • That's what I thought. Message batching is generally contrary to proper design practices. If you are finding there is a need to batch, perhaps you want to use a shared database instead? Commented Aug 31, 2015 at 13:34

2 Answers 2

4

You can retrieve as many messages as you want using the BasicQoS.PrefetchCount:

var model = _rabbitConnection.CreateModel();
// Configure the Quality of service for the model. Below is how what each setting means.
// BasicQos(0="Dont send me a new message untill I’ve finshed",  _fetchSize = "Send me N messages at a time", false ="Apply to this Model only")
model.BasicQos(0, fetchSize, false);

Note: if you set fetchSize = 20 then it will retrieve the first 20 messages that are currently in the queue. But, once the queue has been emptied it won't wait for 20 messages to build up in the queue, it will start consuming them as fast as possible, grabbing up to 20 at a time.

Hopefully that makes sense.

Sign up to request clarification or add additional context in comments.

Comments

1

Thanks for answers, but I've found the class which I looked for: RabbitMQ.Client.QueueingBasicConsumer
Simple implementation is:

IEnumerable<T> Get(int maxBatchCount, int getMessageTimeout, int getBatchTimeout)
{
    var result = new List<T>();
    var startTime = DateTime.Now;
    while (result.Count < maxBatchCount)
    {
        var deliverEventArgs = new BasicDeliverEventArgs();
        if ((_consumer as QueueingBasicConsumer).Queue.Dequeue(GetMessageTimeout, out deliverEventArgs))
        {
            var entry = ContractSerializer.Deserialize<T>(deliverEventArgs.Body);
            result.Add(entry);
            _queue.Channel.BasicAck(deliverEventArgs.DeliveryTag, false);
        }
        else
            break;

        if ((DateTime.Now - startTime) >= TimeSpan.FromMilliseconds(getBatchTimeout))
            break;
    }
    return result;
}

Well, of course, you can use Environment.TickCount instead of DateTime.Now

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.