Azure Service Bus with .NET (Step-by-Step + Code)

In modern software systems, particularly in microservices or decoupled architectures, services often need to communicate with each other without waiting. This is where Azure Service Bus comes in.

Imagine your API receives an image file for processing. Instead of processing it immediately (which might take time), you send a message to a queue saying, “Hey, a new image is ready.” A background service can then pick up that message and perform the processing. This enhances your system's performance, resilience, and scalability.

That’s the magic of message queues, and Azure Service Bus is Microsoft’s enterprise-grade offering for exactly this purpose.

How does it work?

  1. Your application sends a message to a queue using the SqlBulkCopy API.
  2. The queue stores the message securely until a receiver is available.
  3. A worker application listens to the queue and processes incoming messages.
  4. After processing, the message is either completed (removed) or dead-lettered (moved aside for errors).

Setting Up Service Bus in Azure

Go to the Azure portal and,

  • Create a Service Bus Namespace
  • Inside it, create a Queue (e.g., imageprocessorqueue)
  • Under "Shared access policies", get the Connection String

Keep this string safe, you’ll use it in your app to send and receive messages.

Creating Your .NET App

Start by creating a new console app and installing the necessary NuGet package.

dotnet new console -n ServiceBusDemo
cd ServiceBusDemo
dotnet add package Azure.Messaging.ServiceBus

Sender (How to Send Messages)

This is the part of your app (or your Web API) that notifies the queue when an action has occurred, such as “A new image was uploaded.”

Here’s a minimal sender.

using Azure.Messaging.ServiceBus;

string connectionString = "<your-service-bus-connection-string>";
string queueName = "imageprocessorqueue";

await using var client = new ServiceBusClient(connectionString);
ServiceBusSender sender = client.CreateSender(queueName);

string messageBody = "Image uploaded: /images/img123.jpg";
ServiceBusMessage message = new ServiceBusMessage(messageBody);

await sender.SendMessageAsync(message);
Console.WriteLine("Message sent.");

What’s happening?

  • You connect to Azure Service Bus.
  • You create a message object.
  • You send it to the queue.

Receiver (How to Read and Process Messages)

This is the background service (which could be a Worker Service or even a Function App) that continuously listens for messages.

Here’s how to receive and process messages.

using Azure.Messaging.ServiceBus;

string connectionString = "<your-service-bus-connection-string>";
string queueName = "imageprocessorqueue";

await using var client = new ServiceBusClient(connectionString);
ServiceBusProcessor processor = client.CreateProcessor(queueName, new ServiceBusProcessorOptions());
processor.ProcessMessageAsync += async args =>
{
    string body = args.Message.Body.ToString();
    Console.WriteLine($"Received: {body}");

    // Simulate processing
    await Task.Delay(1000);
    Console.WriteLine("Done processing.");

    await args.CompleteMessageAsync(args.Message);
};
processor.ProcessErrorAsync += args =>
{
    Console.WriteLine($"Error occurred: {args.Exception.Message}");
    return Task.CompletedTask;
};
await processor.StartProcessingAsync();
Console.WriteLine("Listening... Press any key to exit.");
Console.ReadKey();
await processor.StopProcessingAsync();

This code,

  • Creates a message listener.
  • On receiving a message, it prints and simulates a task.
  • Marks the message as complete so it’s removed from the queue.

When Should You Use Azure Service Bus?

Use it when you want to decouple components, handle long-running or heavy tasks in the background, or implement reliable communication across services.

Example real-life use cases.

  • Order processing after checkout.
  • Sending email/SMS notifications.
  • Offloading data export/import to background jobs.
  • Microservice-to-microservice messaging.

Pro Tips

  • Always wrap message sending in a try-catch to handle connectivity issues.
  • Use message sessions if you need ordered processing.
  • Leverage dead-letter queues to capture failed messages for later inspection.
  • You can also schedule messages for future delivery.

Final Thoughts

Azure Service Bus is a powerful tool in your architecture toolbox. When combined with .NET, it provides clean, reliable, and scalable messaging with minimal setup. Whether you’re building monoliths or microservices, mastering message queues will set your applications apart in performance and reliability.

Let me know if you’d like a GitHub-ready project template or would like to explore advanced scenarios, such as topics and Subscriptions for a pub-sub architecture.