I have the code below for reading x messages from a service bus queue but it feels a bit clunky, especially when it comes to detecting if there is no more data on the queue
Has anyone been able to get this work in a nicer way?
static async Task<List<string>> ReceiveMessagesAsync(int messageCount)
{
var messsages = new List<string>();
queueClient = new QueueClient(ServiceBusConnectionString, QueueName);
try
{
var messages = new List<Message>();
var options = new MessageHandlerOptions(ExceptionReceivedHandler)
{
MaxConcurrentCalls = 1
};
var startingAt = DateTime.Now;
DateTime? latestMessageReadAt = null;
queueClient.RegisterMessageHandler((message, cancellationToken) =>
{
var json = Encoding.UTF8.GetString(message.Body);
messages.Add(json);
latestMessageReadAt = DateTime.Now;
return Task.CompletedTask;
}, options);
var allMessagesRead = false;
// Wait for the desired number of messages to be received
while (messages.Count < messageCount && allMessagesRead == false)
{
await Task.Delay(10); // Adjust the delay based on your requirements
if (latestMessageReadAt != null)
{
allMessagesRead = DateTime.Now.Subtract(latestMessageReadAt.Value).Duration().Seconds > 10;
}
else
{
allMessagesRead = DateTime.Now.Subtract(startingAt).Duration().Seconds > 10;
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
await queueClient.CloseAsync();
}
return messages;
}
static Task ExceptionReceivedHandler(ExceptionReceivedEventArgs exceptionReceivedEventArgs)
{
Console.WriteLine($"Message handler encountered an exception: {exceptionReceivedEventArgs.Exception}");
var context = exceptionReceivedEventArgs.ExceptionReceivedContext;
Console.WriteLine($"Exception context for troubleshooting:");
Console.WriteLine($"- Endpoint: {context.Endpoint}");
Console.WriteLine($"- Entity Path: {context.EntityPath}");
Console.WriteLine($"- Executing Action: {context.Action}");
return Task.CompletedTask;
}
Paul
I agree and Thank you Panagiotis Kanavas,
.Net 3.1is out of support and utilizing.Net 6.0With Service Bus SDK now has Long Term Support.In order to detect the number of messages received and to close the Receiver, Refer the code below. This code works properly in
.Net 3.1as well as.Net 6.0console app:-Output:-
I have added
await ReceiveAndProcessMessagesAsync(2);to receive only 2 messages from Service Bus.As per the comment by Panagiotis Kanavas, You can implement batching by using the code below:-