Soenneker.Flywheel.Core
4.0.16
Prefix Reserved
See the version list below for details.
dotnet add package Soenneker.Flywheel.Core --version 4.0.16
NuGet\Install-Package Soenneker.Flywheel.Core -Version 4.0.16
<PackageReference Include="Soenneker.Flywheel.Core" Version="4.0.16" />
<PackageVersion Include="Soenneker.Flywheel.Core" Version="4.0.16" />
<PackageReference Include="Soenneker.Flywheel.Core" />
paket add Soenneker.Flywheel.Core --version 4.0.16
#r "nuget: Soenneker.Flywheel.Core, 4.0.16"
#:package Soenneker.Flywheel.Core@4.0.16
#addin nuget:?package=Soenneker.Flywheel.Core&version=4.0.16
#tool nuget:?package=Soenneker.Flywheel.Core&version=4.0.16
Soenneker.Flywheel.Core
Background jobs for .NET with Redis storage, retries, scheduling, and job chains.
Background work. Everything in view.
Queue a typed job, coordinate workers across instances, and follow each execution in the live Blazor dashboard.
The optional Flywheel Dashboard, shown with illustrative demo data.
Explore Flywheel · Dashboard · Run the demo
Setup
Requires .NET 10 and Redis 6.0.9 or newer. Add these packages to your app:
dotnet add package Soenneker.Flywheel.Core
dotnet add package Soenneker.Flywheel.Redis
dotnet add package Soenneker.Flywheel.Generators
Add PrivateAssets="all" to the Generators package reference in your project file.
Usage
In an ASP.NET Core app's Program.cs, register Flywheel and enqueue a job:
using Soenneker.Flywheel.Core.Attributes;
using Soenneker.Flywheel.Core.Registrars;
using Soenneker.Flywheel.Core.Services.Abstract;
using Soenneker.Flywheel.Generated;
using Soenneker.Flywheel.Redis;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddFlywheel(options => options.Workers = 4)
.AddRedis(options => options.ConnectionString = "localhost:6379")
.AddGeneratedJobs();
var app = builder.Build();
var client = app.Services.GetRequiredService<IJobClient>();
await client.Enqueue(FlywheelJobs.MessageJobs_Write,
new Message("Hello from Flywheel"));
await app.RunAsync();
public sealed record Message(string Text);
public sealed class MessageJobs(ILogger<MessageJobs> logger)
{
[FlywheelJob("message.write.v1")]
public Task Write(Message message, CancellationToken cancellationToken)
{
logger.LogInformation("{Message}", message.Text);
return Task.CompletedTask;
}
}
When hosting the optional dashboard API, register its credentials with AddDashboard, map controllers for its HTTP endpoints, and let Flywheel map its authenticated real-time endpoint:
builder.Services.AddFlywheel()
.AddRedis(options => options.ConnectionString = "localhost:6379")
.AddDashboard(options =>
{
options.Username = builder.Configuration["Flywheel:Dashboard:Username"] ?? "";
options.PasswordPhc = builder.Configuration["Flywheel:Dashboard:PasswordPhc"] ?? "";
});
var app = builder.Build();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseRateLimiter();
app.MapControllers();
app.MapFlywheelDashboard();
Enqueue returns after saving the job. Workers run it in the background. In other services, inject IJobClient to submit jobs.
Handlers can inject IJobProgress and publish durable progress while they run:
public sealed class ImportJobs(IJobProgress progress)
{
[FlywheelJob("contacts.import.v1")]
public async Task Import(ImportRequest request, CancellationToken cancellationToken)
{
for (var i = 0; i < request.Contacts.Count; i++)
{
await Import(request.Contacts[i], cancellationToken);
await progress.Report((i + 1d) / request.Contacts.Count * 100, $"Imported {i + 1} contacts", cancellationToken);
}
}
}
Declare distributed execution limits with the job so every server applies the same generated policy before workers start:
[FlywheelJob("contacts.import.v1", MaxConcurrency = 1)]
public Task Import(ImportRequest request, CancellationToken cancellationToken) => // ...
IJobClient.ConfigureMethod remains available for limits that genuinely need to change at runtime.
Queue and schedule jobs
Use IJobClient for immediate, delayed, scheduled, recurring, cron, or chained jobs:
await client.Enqueue(FlywheelJobs.MessageJobs_Write, new Message("Later"),
delay: TimeSpan.FromMinutes(10));
await client.Recurring("hourly-message", FlywheelJobs.MessageJobs_Write,
new Message("Every hour"), TimeSpan.FromHours(1));
await client.Schedule("weekday-message", FlywheelJobs.MessageJobs_Write,
new Message("Good morning"), "0 9 * * MON-FRI",
timeZoneId: "America/Chicago");
See IJobClient for the full API.
Jobs can run more than once; make handlers safe to retry and pass cancellation tokens to async work. Keep job names stable. Reusing a recurring or cron schedule ID leaves the existing schedule unchanged.
Related
- Redis: storage configuration.
- Generators: job method requirements.
- Dashboard: view jobs and logs.
- Demo: run a complete app.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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
- Soenneker.Asyncs.Locks (>= 4.0.78)
- Soenneker.Atomics.ValueInts (>= 4.0.26)
- Soenneker.Cron.Parser (>= 4.0.2)
- Soenneker.Gen.EnumValues (>= 4.0.47)
- Soenneker.Hashing.Pbkdf2 (>= 4.0.33)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Soenneker.Flywheel.Core:
| Package | Downloads |
|---|---|
|
Soenneker.Flywheel.Redis
Redis-backed storage and distributed coordination for Soenneker Flywheel. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 5.0.2 | 0 | 9/8/2026 |
| 5.0.1 | 0 | 9/8/2026 |
| 4.0.21 | 0 | 9/8/2026 |
| 4.0.20 | 18 | 9/7/2026 |
| 4.0.18 | 41 | 9/7/2026 |
| 4.0.17 | 39 | 9/7/2026 |
| 4.0.16 | 41 | 9/7/2026 |
| 4.0.15 | 29 | 9/7/2026 |
| 4.0.14 | 66 | 9/7/2026 |
| 4.0.13 | 43 | 9/7/2026 |
| 4.0.12 | 45 | 9/7/2026 |
| 4.0.11 | 44 | 9/7/2026 |
| 4.0.10 | 46 | 9/7/2026 |
| 4.0.9 | 47 | 9/6/2026 |
| 4.0.8 | 37 | 9/6/2026 |
| 4.0.7 | 48 | 9/6/2026 |
| 4.0.6 | 38 | 9/6/2026 |
| 4.0.5 | 45 | 9/6/2026 |
| 4.0.4 | 46 | 9/6/2026 |
| 4.0.3 | 43 | 9/6/2026 |