PollyAzureServiceBus 1.0.2
dotnet add package PollyAzureServiceBus --version 1.0.2
NuGet\Install-Package PollyAzureServiceBus -Version 1.0.2
<PackageReference Include="PollyAzureServiceBus" Version="1.0.2" />
<PackageVersion Include="PollyAzureServiceBus" Version="1.0.2" />
<PackageReference Include="PollyAzureServiceBus" />
paket add PollyAzureServiceBus --version 1.0.2
#r "nuget: PollyAzureServiceBus, 1.0.2"
#:package PollyAzureServiceBus@1.0.2
#addin nuget:?package=PollyAzureServiceBus&version=1.0.2
#tool nuget:?package=PollyAzureServiceBus&version=1.0.2
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 | Downloads | Description |
|---|---|---|
| PollyHealthChecks | ASP.NET Core health checks for Polly v8 circuit breakers — expose circuit-breaker state (Closed, HalfOpen, Open, Isolated) as /health endpoint responses | |
| PollyBackoff | Backoff delay strategies for Polly v8 resilience pipelines | |
| PollyGrpc | Polly v8 resilience interceptor for gRPC | |
| PollyEFCore | Polly v8 resilience pipelines for Entity Framework Core — wrap every EF Core query and SaveChanges with retry, timeout and circuit-breaker via a single AddPollyResilience() call | |
| PollyRabbitMQ | Polly v8 resilience for RabbitMQ.Client v7+ — retry, circuit-breaker, and timeout for IChannel operations, with built-in RabbitMqTransientErrors predicate covering AlreadyClosedException, BrokerUnreachableException, OperationInterruptedException, and ConnectFailureException | |
| PollyMailKit | Polly v8 resilience pipelines for MailKit — retry, timeout, and circuit-breaker for SmtpClient.SendAsync and any MailKit SMTP operation | |
| PollyMassTransit | Polly v8 resilience pipelines for MassTransit — retry, timeout, and circuit-breaker for IBus.Publish and ISendEndpointProvider.Send | |
| PollyOpenAI | Polly v8 resilience for OpenAI and Azure OpenAI API calls | |
| PollyAzureEventHub | Polly v8 resilience pipelines for Azure Event Hubs — retry, timeout, and circuit-breaker for EventHubProducerClient and EventHubConsumerClient | |
| PollySignalR | Polly v8 reconnect policy for SignalR | |
| PollyElasticsearch | Polly v8 resilience pipelines for Elastic.Clients.Elasticsearch 8+ — retry, timeout, and circuit-breaker for any Elasticsearch operation, plus a built-in ElasticTransientErrors predicate covering rate limiting (429), service unavailability (503), gateway timeouts (504), and connection failures | |
| PollyHangfire | Polly v8 resilience pipelines for Hangfire — retry, timeout, and circuit-breaker for IBackgroundJobClient.Enqueue and Schedule | |
| PollySendGrid | Polly v8 resilience pipelines for SendGrid — retry, timeout, and circuit-breaker for ISendGridClient.SendEmailAsync | |
| PollyMediatR | Polly v8 resilience pipelines for MediatR — add retry, timeout, circuit-breaker, rate-limiting, hedging, and chaos engineering to any MediatR request handler with a single line of DI registration | |
| PollyAzureKeyVault | Polly v8 resilience pipelines for Azure Key Vault — retry, timeout, and circuit-breaker for SecretClient, KeyClient, and CertificateClient | |
| PollyAzureQueueStorage | Polly v8 resilience pipelines for Azure Queue Storage — retry, timeout, and circuit-breaker for Azure.Storage.Queues QueueClient | |
| PollyRedis | Polly v8 resilience for StackExchange.Redis | |
| PollyKafka | Polly v8 resilience for Confluent.Kafka — retry, circuit breaker, and timeout for producers and consumers | |
| PollyAzureTableStorage | Polly v8 resilience pipelines for Azure Table Storage — retry, timeout, and circuit-breaker for Azure.Data.Tables TableClient | |
| PollyCaching | A caching resilience strategy for Polly v8 pipelines | |
| PollyChaos | Chaos engineering and fault-injection resilience strategies for Polly v8 pipelines | |
| PollyBulkhead | Bulkhead isolation strategy for Polly v8 resilience pipelines |
💼 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 is compatible. 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. |
-
net10.0
- Azure.Messaging.ServiceBus (>= 7.20.2)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.10)
- Polly.Core (>= 8.7.0)
-
net8.0
- Azure.Messaging.ServiceBus (>= 7.20.2)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.10)
- Polly.Core (>= 8.7.0)
-
net9.0
- Azure.Messaging.ServiceBus (>= 7.20.2)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.10)
- 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.