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
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="EverTask.Monitor.AspnetCore.SignalR" Version="3.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="EverTask.Monitor.AspnetCore.SignalR" Version="3.0.0" />
                    
Directory.Packages.props
<PackageReference Include="EverTask.Monitor.AspnetCore.SignalR" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add EverTask.Monitor.AspnetCore.SignalR --version 3.0.0
                    
#r "nuget: EverTask.Monitor.AspnetCore.SignalR, 3.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package EverTask.Monitor.AspnetCore.SignalR@3.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=EverTask.Monitor.AspnetCore.SignalR&version=3.0.0
                    
Install as a Cake Addin
#tool nuget:?package=EverTask.Monitor.AspnetCore.SignalR&version=3.0.0
                    
Install as a Cake Tool

EverTask Logo

Build NuGet NuGet NuGet NuGet NuGet

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

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

View Complete Changelog

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.

License

EverTask is licensed under the Apache License 2.0.

See ATTRIBUTION.md for acknowledgements and attributions.


Developed with ❤️ by Giampaolo Gabba

Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
3.0.0 72 10/19/2025
2.0.0 76 10/19/2025
1.5.4 205 5/31/2024
1.5.3 179 5/23/2024
1.5.2 178 4/9/2024
1.5.1 290 11/23/2023
1.5.0 178 11/21/2023
1.4.1 184 11/19/2023
1.4.0 172 11/19/2023
1.3.0 183 11/19/2023