Listen to this Post
MediatR is a popular library in the .NET ecosystem that supports in-process messaging, particularly for implementing the mediator pattern. One of its key features is the ability to publish notifications to multiple handlers without directly coupling them to the publisher. However, there’s a common misconception about its asynchronous behavior. While it may seem asynchronous, the publishing thread waits for all handlers to complete, which can lead to performance bottlenecks.
To address this, you can implement a truly asynchronous notification publishing mechanism. Here’s how:
You Should Know:
1. Asynchronous Notification Handling:
To make MediatR notifications truly asynchronous, you can use `Task.Run` or a background service to offload the handling of notifications to a separate thread. This ensures the publishing thread returns immediately after queuing the notification.
public async Task PublishNotificationAsync(INotification notification, CancellationToken cancellationToken)
{
await Task.Run(() => mediator.Publish(notification, cancellationToken), cancellationToken);
}
2. Using Background Services:
In ASP.NET Core, you can use `BackgroundService` to handle notifications in the background. This approach is ideal for long-running tasks.
public class NotificationBackgroundService : BackgroundService
{
private readonly IMediator _mediator;
public NotificationBackgroundService(IMediator mediator)
{
_mediator = mediator;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
// Fetch and process notifications
await _mediator.Publish(new SomeNotification(), stoppingToken);
await Task.Delay(1000, stoppingToken); // Adjust delay as needed
}
}
}
3. Custom Notification Handlers:
You can create custom handlers to process notifications asynchronously. This allows you to control the flow and ensure handlers don’t block the main thread.
public class SomeNotificationHandler : INotificationHandler<SomeNotification>
{
public async Task Handle(SomeNotification notification, CancellationToken cancellationToken)
{
await Task.Run(() =>
{
// Handle the notification
}, cancellationToken);
}
}
4. Queue-Based Processing:
For more advanced scenarios, consider using a message queue (e.g., RabbitMQ or Azure Service Bus) to decouple notification publishing and handling entirely.
public async Task PublishNotificationAsync(INotification notification)
{
var message = JsonConvert.SerializeObject(notification);
await queueClient.SendAsync(new Message(Encoding.UTF8.GetBytes(message)));
}
What Undercode Say:
MediatR is a powerful tool for decoupling components in a .NET application, but its default notification handling behavior can be misleading. By implementing truly asynchronous mechanisms, such as background services or queue-based processing, you can improve the performance and scalability of your application. Always consider the nature of your notifications and choose the right approach to ensure your system remains responsive and efficient.
For further reading, check out the official MediatR documentation: MediatR GitHub.
References:
Reported By: Milan Jovanovic – Hackers Feeds
Extra Hub: Undercode MoN
Basic Verification: Pass ✅



