EverTask.Monitor.AspnetCore.SignalR
3.0.0
dotnet add package EverTask.Monitor.AspnetCore.SignalR --version 3.0.0
NuGet\Install-Package EverTask.Monitor.AspnetCore.SignalR -Version 3.0.0
<PackageReference Include="EverTask.Monitor.AspnetCore.SignalR" Version="3.0.0" />
<PackageVersion Include="EverTask.Monitor.AspnetCore.SignalR" Version="3.0.0" />
<PackageReference Include="EverTask.Monitor.AspnetCore.SignalR" />
paket add EverTask.Monitor.AspnetCore.SignalR --version 3.0.0
#r "nuget: EverTask.Monitor.AspnetCore.SignalR, 3.0.0"
#:package EverTask.Monitor.AspnetCore.SignalR@3.0.0
#addin nuget:?package=EverTask.Monitor.AspnetCore.SignalR&version=3.0.0
#tool nuget:?package=EverTask.Monitor.AspnetCore.SignalR&version=3.0.0

Overview
EverTask is a high-performance .NET library for background task execution. It handles everything from simple fire-and-forget operations to complex recurring schedules, with persistence that survives application restarts.
If you've used MediatR, you'll feel right at home with the request/handler pattern. But unlike traditional in-memory task queues, EverTask persists tasks to storage, supports multi-queue workload isolation, and scales to extreme loads (>10k tasks/sec) when needed.
Works great with ASP.NET Core, Windows Services, or any .NET project that needs reliable background processing.
Key Features
- 🚀 Background Execution - Fire-and-forget, scheduled, and recurring tasks with elegant API
- 🎯 Multi-Queue Support (v1.6+) - Isolate workloads by priority, resource type, or business domain
- 🔑 Idempotent Task Registration (v1.6+) - Prevent duplicate recurring tasks with unique keys
- ⚡ High-Performance Scheduler (v2.0+) - PeriodicTimerScheduler with 90% less lock contention and zero CPU when idle
- 🔥 Extreme Load Support (v2.0+) - Optional sharded scheduler for >10k tasks/sec scenarios
- 💾 Smart Persistence - Tasks resume after application restarts (SQL Server, SQLite, In-Memory)
- 🔄 Powerful Retry Policies - Built-in linear retry, custom policies, Polly integration
- ⏱️ Timeout Management - Global and per-task timeout configuration
- 📊 Real-Time Monitoring - Local events + SignalR remote monitoring
- 🎨 Fluent Scheduling API - Intuitive recurring task configuration (every minute, hour, day, week, month, cron)
- 🔧 Extensible Architecture - Custom storage, retry policies, and schedulers
- 🏎️ Optimized Performance (v2.0+) - Reflection caching, lazy serialization, DbContext pooling
- 📈 Auto-Scaling Defaults (v2.0+) - Configuration that scales with your CPU cores
- 🔌 Serilog Integration - Detailed structured logging
- ✨ Async All The Way - Fully asynchronous for maximum scalability
Quick Start
Installation
dotnet add package EverTask
dotnet add package EverTask.SqlServer # Or EverTask.Sqlite
Configuration
using EverTask;
var builder = WebApplication.CreateBuilder(args);
// Register EverTask with SQL Server storage
builder.Services.AddEverTask(opt =>
{
opt.RegisterTasksFromAssembly(typeof(Program).Assembly);
})
.AddSqlServerStorage(
builder.Configuration.GetConnectionString("EverTaskDb")!,
opt =>
{
opt.SchemaName = "EverTask";
opt.AutoApplyMigrations = true;
});
var app = builder.Build();
app.Run();
Create Your First Task
Define a task request:
public record SendWelcomeEmailTask(string UserEmail, string UserName) : IEverTask;
Create a handler:
public class SendWelcomeEmailHandler : EverTaskHandler<SendWelcomeEmailTask>
{
private readonly IEmailService _emailService;
private readonly ILogger<SendWelcomeEmailHandler> _logger;
public SendWelcomeEmailHandler(IEmailService emailService, ILogger<SendWelcomeEmailHandler> logger)
{
_emailService = emailService;
_logger = logger;
}
public override async Task Handle(SendWelcomeEmailTask task, CancellationToken cancellationToken)
{
_logger.LogInformation("Sending welcome email to {Email}", task.UserEmail);
await _emailService.SendWelcomeEmailAsync(
task.UserEmail,
task.UserName,
cancellationToken);
}
}
Dispatch the task:
public class UserController : ControllerBase
{
private readonly ITaskDispatcher _dispatcher;
public UserController(ITaskDispatcher dispatcher) => _dispatcher = dispatcher;
[HttpPost("register")]
public async Task<IActionResult> RegisterUser(UserRegistrationDto dto)
{
// Create user...
// Send welcome email in background
await _dispatcher.Dispatch(new SendWelcomeEmailTask(dto.Email, dto.Name));
return Ok();
}
}
Documentation
📚 Full Documentation - Complete guides, tutorials, and API reference
Quick Links
- Getting Started - Installation, configuration, and your first task
- Task Creation - Requests, handlers, lifecycle hooks, and best practices
- Task Dispatching - Fire-and-forget, delayed, and scheduled tasks
- Recurring Tasks - Fluent scheduling API, cron expressions, idempotent registration
- Advanced Features - Multi-queue, sharded scheduler, continuations, cancellation
- Resilience & Error Handling - Retry policies, timeouts, CancellationToken usage
- Monitoring - Events, SignalR integration, custom monitoring
- Storage Configuration - SQL Server, SQLite, In-Memory, custom implementations
- Configuration Reference - Complete configuration documentation
- Configuration Cheatsheet - Quick reference for all config options
- Architecture & Internals - How EverTask works under the hood
Showcase: Powerful Features
Fluent Recurring Scheduler
Schedule recurring tasks with an intuitive, type-safe API:
// Run every day at 3 AM
await dispatcher.Dispatch(
new DailyCleanupTask(),
builder => builder.Schedule().EveryDay().AtTime(new TimeOnly(3, 0)));
// Run every Monday, Wednesday, Friday at 9 AM
var days = new[] { DayOfWeek.Monday, DayOfWeek.Wednesday, DayOfWeek.Friday };
await dispatcher.Dispatch(
new BackupTask(),
builder => builder.Schedule().EveryWeek().OnDays(days).AtTime(new TimeOnly(9, 0)));
// Run on the first day of every month
await dispatcher.Dispatch(
new MonthlyBillingTask(),
builder => builder.Schedule().EveryMonth().OnDay(1));
// Complex: Every 15 minutes during business hours, weekdays only
await dispatcher.Dispatch(
new HealthCheckTask(),
builder => builder.Schedule().UseCron("*/15 9-17 * * 1-5"));
// Limit executions: Run daily for 30 days, then stop
await dispatcher.Dispatch(
new TrialFeatureTask(userId),
builder => builder.Schedule()
.EveryDay()
.MaxRuns(30)
.RunUntil(DateTimeOffset.UtcNow.AddDays(30)));
Multi-Queue Workload Isolation
Keep critical tasks separate from heavy background work:
builder.Services.AddEverTask(opt =>
{
opt.RegisterTasksFromAssembly(typeof(Program).Assembly);
})
// High-priority queue for critical operations
.AddQueue("critical", q => q
.SetMaxDegreeOfParallelism(20)
.SetChannelCapacity(500)
.SetDefaultTimeout(TimeSpan.FromMinutes(2)))
// Background queue for CPU-intensive work
.AddQueue("background", q => q
.SetMaxDegreeOfParallelism(2)
.SetChannelCapacity(100))
// Email queue for bulk operations
.AddQueue("email", q => q
.SetMaxDegreeOfParallelism(10)
.SetChannelCapacity(10000)
.SetFullBehavior(QueueFullBehavior.FallbackToDefault))
.AddSqlServerStorage(connectionString);
Route tasks to queues:
public class PaymentProcessingHandler : EverTaskHandler<ProcessPaymentTask>
{
public override string? QueueName => "critical"; // High-priority queue
public override async Task Handle(ProcessPaymentTask task, CancellationToken cancellationToken)
{
// Critical payment processing
}
}
Idempotent Task Registration
Use unique keys to safely register recurring tasks at startup without creating duplicates:
// At application startup
public class RecurringTasksRegistrar : IHostedService
{
private readonly ITaskDispatcher _dispatcher;
public async Task StartAsync(CancellationToken ct)
{
// Register recurring tasks - safe to call on every startup
await _dispatcher.Dispatch(
new DailyCleanupTask(),
r => r.Schedule().EveryDay().AtTime(new TimeOnly(3, 0)),
taskKey: "daily-cleanup"); // Won't create duplicates
await _dispatcher.Dispatch(
new HealthCheckTask(),
r => r.Schedule().Every(5).Minutes(),
taskKey: "health-check");
await _dispatcher.Dispatch(
new WeeklySummaryTask(),
r => r.Schedule().EveryWeek().OnDay(DayOfWeek.Monday).AtTime(new TimeOnly(8, 0)),
taskKey: "weekly-summary");
}
public Task StopAsync(CancellationToken ct) => Task.CompletedTask;
}
builder.Services.AddHostedService<RecurringTasksRegistrar>();
What's New in v2.0
Version 2.0 is all about performance. We've optimized every hot path and made the defaults much smarter.
Scheduler Improvements
- PeriodicTimerScheduler is now the default, cutting lock contention by 90% and using zero CPU when idle
- ShardedScheduler available for extreme loads—delivers 2-4x throughput when you're scheduling >10k tasks/sec
Storage Optimizations
- DbContext pooling makes storage operations 30-50% faster
- SQL Server now uses stored procedures, cutting status update roundtrips in half
Dispatcher Performance
- Reflection caching speeds up repeated task dispatching by 93% (~150μs → ~10μs)
- Lazy serialization eliminates unnecessary JSON conversion entirely
Worker Executor Enhancements
- Event data caching slashes monitoring serializations by 99% (60k-80k → ~10-20 per 10k tasks)
- Handler options caching eliminates 99% of runtime casts
- Parallel pending task processing makes startup 80% faster with 1000+ queued tasks
Auto-Scaling Configuration
No more manual tuning—defaults now scale with your CPU cores:
MaxDegreeOfParallelism:Environment.ProcessorCount * 2(previously hardcoded to 1)ChannelCapacity:Environment.ProcessorCount * 200(previously hardcoded to 500)
Better Developer Experience
- Configuration validation catches problems early with helpful warnings
- Zero-allocation patterns on .NET 7+
- Thread safety improvements and race condition fixes throughout
Quick Links
📦 NuGet Packages
- EverTask - Core library
- EverTask.SqlServer - SQL Server storage
- EverTask.Sqlite - SQLite storage
- EverTask.Serilog - Serilog integration
- EverTask.Monitor.AspnetCore.SignalR - Real-time monitoring
📝 Resources
- Changelog - Version history and release notes
- Attribution - Acknowledgements and license information
- GitHub Repository - Source code and issues
- Examples - Sample applications (ASP.NET Core, Console)
Roadmap
We have some exciting features in the pipeline:
- Web Dashboard: A simple web UI for monitoring and managing tasks
- WebAPI Endpoints: RESTful API for remote task management
- Additional Monitoring: Sentry Crons, Application Insights, OpenTelemetry support
- More Storage Options: PostgreSQL, MySQL, Redis, Cosmos DB
- Clustering: Multi-server task distribution with load balancing and failover
Contributing
Contributions are welcome! Bug reports, feature requests, and pull requests all help make EverTask better.
- Report issues: https://github.com/GiampaoloGabba/EverTask/issues
- Contribute code: https://github.com/GiampaoloGabba/EverTask/pulls
License
EverTask is licensed under the Apache License 2.0.
See ATTRIBUTION.md for acknowledgements and attributions.
Developed with ❤️ by Giampaolo Gabba
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. 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. |
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.