Some time ago I got a question from Eto: “How would I go about this if I just want to receive one message only?” And I started thinking… is it possible in .Net Core?
I used the newest Microsoft.Azure.ServiceBus package, that is dedicated for .Net Core, but there is no method to receive only one message. So I used regular RegisterMessageHandler with a twist:
public void ReceiveOne() { var queueClient = new QueueClient(ServiceBusConnectionString, "go_testing"); queueClient.RegisterMessageHandler( async (message, token) => { var messageBody = Encoding.UTF8.GetString(message.Body); Console.WriteLine($"Received: {messageBody}, time: {DateTime.Now}"); await queueClient.CompleteAsync(message.SystemProperties.LockToken); await queueClient.CloseAsync(); }, new MessageHandlerOptions(async args => Console.WriteLine(args.Exception)) { MaxConcurrentCalls = 1, AutoComplete = false }); }
As you can see it is a standard approach, but after successfully processed message, I close queueClient. This works and it receives only one message, but it also gives an error.
I wasn’t fully satisfied with the solution, so I asked a question on StackOverflow: https://stackoverflow.com/questions/50438466/azure-service-bus-in-net-core-how-to-receive-only-one-message
After a few hours, I got an answer, that it is possible and I should just… use different package!
Using the old package
So far I didn’t manage to use old package in .NetCore project. So in order to install package WindowsAzure.ServiceBus, you need to have project referencing full framework.
And here is the code:
public async Task ReceiveOne() { var queueClient = QueueClient.CreateFromConnectionString(ServiceBusConnectionString, "go_testing", ReceiveMode.PeekLock); var message = await queueClient.ReceiveAsync(); Console.WriteLine($"Received: {message.GetBody<string>()}, time: {DateTime.Now}"); await message.CompleteAsync(); }
So that’s it and it works, but sadly not in .Net Core. However, I’ll keep this post up to date when such thing will be possible.
Your solution is not a solution…
The only people stumbling across this post will be dotnet core users.
I cannot agree. It is a way to solve a problem, but you’re right that it will only work in .net core. More and more projects runs on .net core, so I cannot say it’s a flaw.
However, getting back to the solution, I think there is a better way to solve it. Azure Service Bus has REST API and it might be the right path for this problem.
Current solution is to switch to Azure.Messaging.ServiceBus and use:
– ServiceBusSender – to send a single/multiple message
– ServiceBusReceiver – to receive a single message
– ServiceBusProcessor – to process messages asynchronously
Docs: https://azuresdkdocs.blob.core.windows.net/$web/dotnet/Azure.Messaging.ServiceBus/7.1.0/index.html