4

Receiving Messages in Azure Service Bus

 3 years ago
source link: https://www.pmichaels.net/2020/12/26/receiving-messages-in-azure-service-bus/?utm_campaign=receiving-messages-in-azure-service-bus
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

In this post I covered the basics of setting up a queue and sending a message to it. Here, I’m going to cover the options around receiving that message.

Essentially, there are two possibilities here: you can either set-up an event listener, or you can poll the queue directly, and receive the messages one at a time.

Option 1 – Events

The events option seems to be the one that Microsoft now prefer – essentially, you register a handler and then as the messages come in, you simply handle them inside an event. The code here looks something like this:

var queueClient = new QueueClient(connectionString, "test-queue");
var messageHandlerOptions = new MessageHandlerOptions(ExceptionHandler);
queueClient.RegisterMessageHandler(handleMessage, messageHandlerOptions);

The event handlers:

private static Task ExceptionHandler(ExceptionReceivedEventArgs arg)
{
Console.WriteLine("Something bad happened!");
return Task.CompletedTask;
}
private static Task handleMessage(Message message, CancellationToken cancellation)
{
string messageBody = Encoding.UTF8.GetString(message.Body);
Console.WriteLine("Message received: {0}", messageBody);
return Task.CompletedTask;
}

Option 2 – Polling

With this option, you simply ask for a message. You’ll need to use the approach for things like deferred messages (which I hope to cover in a future post):

var messageReceiver = new MessageReceiver(connectionString, "test-queue", ReceiveMode.ReceiveAndDelete);           
var message = await messageReceiver.ReceiveAsync();
string messageBody = Encoding.UTF8.GetString(message.Body);           
Console.WriteLine("Message received: {0}", messageBody);

Option 3 – Option 1, but cruelly force it into option 2

I thought I’d include this, although I would strongly advise against using it in most cases. If you wish, you can register an event, but force the event into a procedural call, so that you can await it finishing. You can do this by using the TaskCompletionSource. First, declare a TaskCompletionSource in your code (somewhere accessible):

private static TaskCompletionSource<bool> _taskCompletionSource;

Then, in handleMessage (see above), when you’ve received the message you want, set the result:

if (message.CorrelationId == correlationId)
{
await client.CompleteAsync(message.SystemProperties.LockToken);
_taskCompletionSource.SetResult(true);
}

Finally, after you’ve registered the message handler, just await this task:

queueClient.RegisterMessageHandler(
(message, cancellationToken) => handleMessage(correlationId, queueClient, message, cancellationToken),
messageHandlerOptions);
await _taskCompletionSource.Task;

References

Advanced Features with Azure Service Bus


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK