PollyAzureServiceBus 1.0.1
dotnet add package PollyAzureServiceBus --version 1.0.1
NuGet\Install-Package PollyAzureServiceBus -Version 1.0.1
<PackageReference Include="PollyAzureServiceBus" Version="1.0.1" />
<PackageVersion Include="PollyAzureServiceBus" Version="1.0.1" />
<PackageReference Include="PollyAzureServiceBus" />
paket add PollyAzureServiceBus --version 1.0.1
#r "nuget: PollyAzureServiceBus, 1.0.1"
#:package PollyAzureServiceBus@1.0.1
#addin nuget:?package=PollyAzureServiceBus&version=1.0.1
#tool nuget:?package=PollyAzureServiceBus&version=1.0.1
PollyAzureServiceBus
Polly v8 resilience for Azure Service Bus — automatic retry, circuit breaker, and per-operation timeout for sending and receiving messages. Drop-in wrappers for ServiceBusSender and ServiceBusReceiver, no configuration changes required.
Why PollyAzureServiceBus?
The Azure Service Bus SDK ships with its own retry policy, but it only covers a subset of transient failures and cannot be composed with your broader application resilience strategy. PollyAzureServiceBus gives you the full power of Polly v8 — exponential back-off with jitter, circuit breaker isolation, per-call timeouts, and telemetry hooks — applied consistently to every send and receive operation.
| Feature | Azure SDK retry | PollyAzureServiceBus |
|---|---|---|
| Exponential back-off with jitter | ❌ | ✅ |
| Circuit breaker | ❌ | ✅ |
| Per-operation timeout | ❌ | ✅ |
| Composable with app resilience | ❌ | ✅ |
| DI registration | ❌ | ✅ |
| Targets net8 + net9 | ✅ | ✅ |
Installation
dotnet add package PollyAzureServiceBus
Quick Start
Sender
var client = new ServiceBusClient(connectionString);
// Extension method on ServiceBusClient
var sender = client.CreateResilientSender("my-queue", o =>
{
o.MaxRetries = 3;
o.BaseDelay = TimeSpan.FromMilliseconds(500);
o.OperationTimeout = TimeSpan.FromSeconds(30);
});
await sender.SendMessageAsync(new ServiceBusMessage("Hello, World!"));
Receiver
var receiver = client.CreateResilientReceiver("my-queue");
// or for topic subscriptions:
var receiver = client.CreateResilientReceiver("my-topic", "my-subscription");
var message = await receiver.ReceiveMessageAsync();
if (message is not null)
{
// process message...
await receiver.CompleteMessageAsync(message);
}
With Dependency Injection
// Program.cs
builder.Services.AddResilientServiceBusSender(
connectionString: Environment.GetEnvironmentVariable("SERVICE_BUS_CONNECTION")!,
queueOrTopicName: "orders",
configure: o =>
{
o.MaxRetries = 3;
o.OperationTimeout = TimeSpan.FromSeconds(30);
});
builder.Services.AddResilientServiceBusReceiver(
connectionString: Environment.GetEnvironmentVariable("SERVICE_BUS_CONNECTION")!,
queueName: "orders");
// Inject ResilientServiceBusSender / ResilientServiceBusReceiver
With Managed Identity (DefaultAzureCredential)
using Azure.Identity;
var credential = new DefaultAzureCredential();
var client = new ServiceBusClient("mynamespace.servicebus.windows.net", credential);
var sender = client.CreateResilientSender("my-queue");
Configuration
var options = new PollyServiceBusOptions
{
// Retry
MaxRetries = 3, // 0 = no retry
BaseDelay = TimeSpan.FromMilliseconds(500), // exponential base
MaxDelay = TimeSpan.FromSeconds(30),
// Circuit breaker
CircuitBreakerFailureRatio = 0.5,
CircuitBreakerMinimumThroughput = 10,
CircuitBreakerSamplingDuration = TimeSpan.FromSeconds(30),
CircuitBreakerBreakDuration = TimeSpan.FromSeconds(5),
// Timeout
OperationTimeout = TimeSpan.FromSeconds(30),
// Which failure reasons are treated as transient (eligible for retry)
TransientFailureReasons = new HashSet<ServiceBusFailureReason>
{
ServiceBusFailureReason.ServiceCommunicationProblem,
ServiceBusFailureReason.ServiceTimeout,
ServiceBusFailureReason.ServiceBusy,
ServiceBusFailureReason.GeneralError,
},
};
| Property | Default | Description |
|---|---|---|
MaxRetries |
3 |
Retry attempts (0 = disabled) |
BaseDelay |
500 ms |
Base delay for exponential back-off with jitter |
MaxDelay |
30 s |
Cap for exponential back-off delay |
CircuitBreakerFailureRatio |
0.5 |
Failure ratio to open circuit |
CircuitBreakerMinimumThroughput |
10 |
Minimum calls before CB can open |
CircuitBreakerSamplingDuration |
30 s |
Sliding window for failure ratio |
CircuitBreakerBreakDuration |
5 s |
How long the circuit stays open |
OperationTimeout |
30 s |
Max time per operation before TimeoutRejectedException |
TransientFailureReasons |
see above | ServiceBusFailureReason set that triggers retry/CB |
API Reference
ResilientServiceBusSender
| Method | Description |
|---|---|
SendMessageAsync(message, ct) |
Send a single message |
SendMessagesAsync(messages, ct) |
Send a batch of messages |
ScheduleMessageAsync(message, time, ct) |
Schedule a message for future delivery |
CancelScheduledMessageAsync(seqNum, ct) |
Cancel a scheduled message |
ResilientServiceBusReceiver
| Method | Description |
|---|---|
ReceiveMessageAsync(maxWait, ct) |
Receive a single message (returns null on timeout) |
ReceiveMessagesAsync(max, maxWait, ct) |
Receive a batch of messages |
CompleteMessageAsync(message, ct) |
Complete (delete) a message |
AbandonMessageAsync(message, props, ct) |
Return message to queue |
DeadLetterMessageAsync(message, reason, desc, ct) |
Move message to dead-letter queue |
Error Handling
Non-transient ServiceBusExceptions (e.g. MessagingEntityNotFound, MessageSizeExceeded) are rethrown as-is. After retries are exhausted the last exception is a TransientServiceBusException wrapping the original:
try
{
await sender.SendMessageAsync(message);
}
catch (TransientServiceBusException ex)
{
// All retries failed
Console.WriteLine($"Service Bus failure: {ex.Reason} — {ex.ServiceBusException.Message}");
}
catch (BrokenCircuitException)
{
// Circuit is open — fail fast without hitting the broker
}
catch (TimeoutRejectedException)
{
// Operation exceeded OperationTimeout
}
Resilience Pipeline Order
Retry → Circuit Breaker → Timeout → Service Bus operation
Related Packages
| Package | Description |
|---|---|
| PollyElasticsearch | Polly v8 for Elastic.Clients.Elasticsearch |
| PollyAzureKeyVault | Polly v8 for Azure Key Vault |
| PollyAzureEventHub | Polly v8 for Azure Event Hubs |
| PollySendGrid | Polly v8 for SendGrid |
| PollyMassTransit | Polly v8 for MassTransit |
| PollyAzureTableStorage | Polly v8 for Azure Table Storage |
| PollyMailKit | MailKit SMTP email client |
| PollyAzureQueueStorage | Azure Queue Storage QueueClient |
| PollyHangfire | Hangfire IBackgroundJobClient |
| PollyBackoff | Advanced back-off strategies with jitter |
| PollyChaos | Chaos engineering — inject faults in tests |
| PollyMediatR | Polly pipeline behaviour for MediatR |
| PollyEFCore | Resilient EF Core execution strategies |
| PollyHealthChecks | Health check endpoints for Polly circuits |
| PollyOpenAI | Retry + rate-limit handling for OpenAI / Azure OpenAI |
| PollyRedis | Resilient StackExchange.Redis wrapper |
| PollySignalR | Reconnect policy for SignalR HubConnection |
| PollyGrpc | Polly v8 resilience for gRPC .NET clients |
| PollyKafka | Polly v8 resilience for Confluent.Kafka producers and consumers |
| PollyCaching | Distributed cache with Polly resilience |
| PollyBulkhead | Bulkhead isolation for concurrent workloads |
| PollyRabbitMQ | Polly v8 resilience for RabbitMQ.Client channels |
💼 Need .NET consulting?
The author of this package is available for consulting on Polly v8 resilience, Azure cloud architecture, and clean .NET design.
→ solidqualitysolutions.com · LinkedIn
License
MIT
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- Azure.Messaging.ServiceBus (>= 7.20.1)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.2)
- Polly.Core (>= 8.7.0)
-
net9.0
- Azure.Messaging.ServiceBus (>= 7.20.1)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.2)
- Polly.Core (>= 8.7.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.