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
                    
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="MiladRv.Asyncify.Net" Version="2.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="MiladRv.Asyncify.Net" Version="2.0.1" />
                    
Directory.Packages.props
<PackageReference Include="MiladRv.Asyncify.Net" />
                    
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 MiladRv.Asyncify.Net --version 2.0.1
                    
#r "nuget: MiladRv.Asyncify.Net, 2.0.1"
                    
#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 MiladRv.Asyncify.Net@2.0.1
                    
#: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=MiladRv.Asyncify.Net&version=2.0.1
                    
Install as a Cake Addin
#tool nuget:?package=MiladRv.Asyncify.Net&version=2.0.1
                    
Install as a Cake Tool

Asyncify.Net

NuGet Build License: MIT .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

  1. A request hits an endpoint marked with [AsyncRequest]
  2. The middleware intercepts it before the controller runs
  3. The controller is resolved from the DI container and method arguments are extracted from the HTTP request
  4. The synchronous method is dispatched to a background thread via Task.Run
  5. A trackId is returned immediately to the caller
  6. 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.

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/my-feature)
  3. Commit your changes
  4. Open a pull request

License

Distributed under the MIT License. See LICENSE for details.

Product 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. 
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
2.0.1 79 5/24/2026
2.0.0 77 5/24/2026