MiladRv.Asyncify.Net
2.0.1
dotnet add package MiladRv.Asyncify.Net --version 2.0.1
NuGet\Install-Package MiladRv.Asyncify.Net -Version 2.0.1
<PackageReference Include="MiladRv.Asyncify.Net" Version="2.0.1" />
<PackageVersion Include="MiladRv.Asyncify.Net" Version="2.0.1" />
<PackageReference Include="MiladRv.Asyncify.Net" />
paket add MiladRv.Asyncify.Net --version 2.0.1
#r "nuget: MiladRv.Asyncify.Net, 2.0.1"
#:package MiladRv.Asyncify.Net@2.0.1
#addin nuget:?package=MiladRv.Asyncify.Net&version=2.0.1
#tool nuget:?package=MiladRv.Asyncify.Net&version=2.0.1
Asyncify.Net
Run your heavy synchronous controller actions in the background — without changing a single line of business logic. Just add an attribute, and your endpoint immediately returns a trackId that the client can use to poll for the result.
POST /products/import → { "trackId": "3fa85f64..." } (instant)
GET /async?trackId=… → { "status": "Pending" }
GET /async?trackId=… → { "status": "Complete", "result": { … } }
Requirements
- .NET 8 or .NET 10
Installation
dotnet add package Asyncify.Net
Setup
1 — Register the service
In Program.cs, before builder.Build():
builder.Services.AddAsyncRequest();
2 — Register the middleware
After builder.Build():
app.UseAsyncRequest();
Usage
Step 1 — Mark the controller
Add [AsyncController] to the controller class and pass its own type:
[AsyncController(typeof(ProductsController))]
public class ProductsController : Controller
{
private readonly IProductService _productService;
public ProductsController(IProductService productService)
{
_productService = productService;
}
[AsyncRequest(nameof(ImportProducts))]
[HttpPost("import")]
public IActionResult ImportProducts([FromBody] ImportRequest request)
{
// Heavy work goes here — no async/await needed.
_productService.BulkImport(request.Items);
return Ok();
}
}
Step 2 — Call the endpoint
The response comes back instantly with a trackId:
{
"trackId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"status": "Pending",
"result": null
}
Step 3 — Poll for the result
GET /async?trackId=3fa85f64-5717-4562-b3fc-2c963f66afa6
{
"trackId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"status": "Complete",
"result": { ... }
}
Request Status
| Status | Description |
|---|---|
Pending |
The job has been queued but not finished yet |
Complete |
The job finished successfully |
Failed |
The job threw an unexpected exception |
Timeout |
The job exceeded the allowed execution time |
Endpoints added automatically
UseAsyncRequest() registers two endpoints on your application:
| Method | Path | Description |
|---|---|---|
GET |
/async |
Poll for the result using ?trackId={guid} |
GET |
/api/health |
Simple health check — returns 200 OK |
Supported HTTP methods
Arguments are resolved automatically based on their binding attributes:
| HTTP Method | Argument source |
|---|---|
GET |
[FromQuery], [FromRoute] |
POST |
[FromBody], [FromRoute] |
PUT |
[FromBody], [FromRoute] |
DELETE |
[FromRoute] |
How it works
- A request hits an endpoint marked with
[AsyncRequest] - The middleware intercepts it before the controller runs
- The controller is resolved from the DI container and method arguments are extracted from the HTTP request
- The synchronous method is dispatched to a background thread via
Task.Run - A
trackIdis returned immediately to the caller - The caller polls
GET /async?trackId=…to check progress and retrieve the result
Contributing
Contributions are welcome. Please open an issue first to discuss what you would like to change, then submit a pull request against the develop branch.
- Fork the repository
- Create a feature branch (
git checkout -b feature/my-feature) - Commit your changes
- Open a pull request
License
Distributed under the MIT License. See LICENSE for details.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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 was computed. 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 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
- Microsoft.AspNetCore.OpenApi (>= 10.0.8)
- Newtonsoft.Json (>= 13.0.4)
- Swashbuckle.AspNetCore (>= 10.1.7)
- Swashbuckle.AspNetCore.Annotations (>= 10.1.7)
-
net8.0
- Microsoft.AspNetCore.OpenApi (>= 8.0.19)
- Newtonsoft.Json (>= 13.0.4)
- Swashbuckle.AspNetCore (>= 10.1.7)
- Swashbuckle.AspNetCore.Annotations (>= 10.1.7)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.