4

There are two approaches for a service worker to process messages from an Azure Service Bus Queue:

while (!ExitRequested)
{
    try
    {
        var message = await _queueClient.ReceiveAsync(TimeSpan.FromSeconds(1));

        if (message != null)
            ProcessIt(message);
    }
    catch (Exception ex)
    {
        HandleIt(ex);
    }
}

or with the EAP:

var onMessageOptions = new OnMessageOptions();

onMessageOptions.ExceptionReceived += (sender, args) => HandleIt(args.Exception);

_queueClient.OnMessageAsync(ProcessIt, onMessageOptions);

WaitFor(ExitRequested);

What are advantages and disadvantages of the two approaches? Which one should be picked in which particular scenario?

Stefano d'Antonio
  • 5,874
  • 3
  • 32
  • 45

1 Answers1

2

ReceiveAsync is a part of the ASB .NET client API. OnMessage API is way the native ASB client offers to simplify creation of concurrent message pumps, allowing you a few features "out of the box" so that you don't have to handle those manually. Among those are:

  1. Easy registration of your message pump as a callback
  2. Message auto completion
  3. Auto renew timeout to simplify lock tokens renewal
  4. Handling of concurrent pumps/callbacks

These advantages can be also viewed as disadvantages when you need the flexibility and tight control over things. For example, if you need to control how message completion is performed, you'd turn auto completion off and do it yourself. But, when you need to process more than a single incoming message at a time in your callback, OnMessage API won't let you, since it's providing one message at a time, you better off with [ReceiveBatchAsync][1]. I had a post about OnMessage API benefits you can review.

Which one should be picked in which particular scenario?

This is something you need to answer yourself based on what your requirements and architecture are going to be. If you do not require tight control over things and going to handle one message at a time (given you can execute concurrently multiple message processing), OnMessage API is an easy path to start with and ASB client does a good job. In case you need to process batches and control a lot of lower level aspects, go with MessageSender/MessageReceiver approach.

Sean Feldman
  • 23,443
  • 7
  • 55
  • 80
  • Good point about the `ReceiveBatch`, but I was only interested in performances/limitations of the `Receive` vs `OnMessage` for single messages. They can also both handle completions/lock in they way you prefer. Unless they are both exposed for compatibility/consistency reasons only, I would like to see when to use one or the other (in single msg scenarios) – Stefano d'Antonio Oct 30 '16 at 07:37
  • Perhaps you should update your question as it did not emphasize the performance concern. – Sean Feldman Oct 30 '16 at 18:22
  • I'm not too concerned about performances in particular, I'm curious about any difference in the two patterns, including performances if any. – Stefano d'Antonio Oct 31 '16 at 09:20
  • Just a comment: A service bus topic subscription with MaxDeliveryCount=10. With ReceiveAsync, the listener only receives a single event from each message. With OnMessageAsync, the listener receives 10 events from the same message. – HuorSwords Apr 06 '17 at 11:29
  • MaxDeliberyCount does not mean "deliver maximum 10 messages", but "a message can be delivered up to 10 times" . – Sean Feldman Apr 06 '17 at 13:47