BackgroundTaskQueue.AspNetCore
2.0.1
dotnet add package BackgroundTaskQueue.AspNetCore --version 2.0.1
NuGet\Install-Package BackgroundTaskQueue.AspNetCore -Version 2.0.1
<PackageReference Include="BackgroundTaskQueue.AspNetCore" Version="2.0.1" />
<PackageVersion Include="BackgroundTaskQueue.AspNetCore" Version="2.0.1" />
<PackageReference Include="BackgroundTaskQueue.AspNetCore" />
paket add BackgroundTaskQueue.AspNetCore --version 2.0.1
#r "nuget: BackgroundTaskQueue.AspNetCore, 2.0.1"
#:package BackgroundTaskQueue.AspNetCore@2.0.1
#addin nuget:?package=BackgroundTaskQueue.AspNetCore&version=2.0.1
#tool nuget:?package=BackgroundTaskQueue.AspNetCore&version=2.0.1
BackgroundTaskQueue.AspNetCore
A simple and scalable way to queue fire-and-forget background work in ASP.NET Core using dependency injection, scoped lifetimes, and category-based parallelism.
This service enables background work execution without requiring hosted services in your own code, while supporting graceful shutdown, cancellation, and error handling.
Features
- Scoped dependency injection for background tasks
- Optional named categories with configurable concurrency and queueing
- Bounded capacity with task rejection
- Graceful cancellation on shutdown
- Customizable exception logging via
IOffloadWorkExceptionLogger
- Agressive unit testing
Installation
Register the service with default configuration:
// Defaults to a MaxDegreeOfParallelism of 3, unbounded capacity
builder.Services.AddOffloadWorkService();
Or customize the default configuration:
builder.Services.AddOffloadWorkService((OffloadWorkServiceOptions opt) =>
{
// Controls how many tasks can run concurrently
opt.MaxDegreeOfParallelism = 5;
// Limits the number of active tasks (-1 for unlimited)
opt.BoundedCapacity = 100;
});
Or define multiple named categories:
builder.Services.AddOffloadWorkService((OffloadWorkServiceCategoryOptions cat) =>
{
cat.AddCategory("email", new OffloadWorkServiceOptions
{
MaxDegreeOfParallelism = 2,
BoundedCapacity = 10
});
cat.AddCategory("pdf", new OffloadWorkServiceOptions
{
MaxDegreeOfParallelism = 4,
BoundedCapacity = -1 // unbounded
});
});
Usage
Inject IOffloadWorkService
into your controller or service.
public sealed class MyController: ControllerBase
{
private readonly IOffloadWorkService _offloader;
public MyController(IOffloadWorkService offloadWorkService)
{
_offloader = offloadWorkService;
}
}
Offload to the default category:
[HttpPost, Route("reindex")]
public IActionResult Reindex()
{
var accepted = _offloader.Offload(async (sp, _, ct) =>
{
var search = sp.GetRequiredService<ISearchIndexer>();
await search.ReindexAsync(ct);
}, param: default);
return accepted ? Accepted() :
StatusCode(StatusCodes.Status429TooManyRequests, "Queue full");
}
Offload to a named category:
[HttpPost, Route("send-email")]
public IActionResult SendEmail([FromBody] EmailRequest request)
{
var accepted = _offloader.Offload("email", async (sp, data, ct) =>
{
var sender = sp.GetRequiredService<IEmailSender>();
await sender.SendAsync(data.To, data.Subject, data.Body, ct);
}, request);
return accepted ? Accepted() :
StatusCode(StatusCodes.Status429TooManyRequests, "Email queue full");
}
Checking Queue Length
You can also retrieve the current length of the task queue for monitoring or logging purposes:
var queueLength = _offloader.GetActiveCount();
var queueLengthEmail = _offloader.GetActiveCount("email");
Custom Exception Logging
Implement a custom logger to capture exceptions from background tasks.
public sealed class MyExceptionLogger : IOffloadWorkExceptionLogger
{
public void Log(Exception ex, string? category)
{
// Send to telemetry, logger, etc.
}
}
Register it:
builder.Services.AddTransient<IOffloadWorkExceptionLogger, MyExceptionLogger>();
If registered, it will be used in place of the default ILogger<OffloadWorkService>
for exceptions.
Behavior
BoundedCapacity
is total active + queued items- Offload returns
false
if the queue is full - Background tasks receive a scoped
IServiceProvider
- Cancellation tokens are honored during shutdown
- Logging is customizable but falls back to
ILogger
if needed
Clean Shutdown
The service cancels all running and queued tasks during shutdown using linked cancellation tokens. Resources are disposed automatically.
Contributing
Contributions are welcome! If you have improvements or bug fixes, please open an issue or submit a pull request.
License
This project is licensed under the MIT License.
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 was computed. 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. |
-
net6.0
- No dependencies.
-
net8.0
- No dependencies.
-
net9.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.