ReactiveLock.Core 0.0.15

Prefix Reserved
There is a newer version of this package available.
See the version list below for details.
dotnet add package ReactiveLock.Core --version 0.0.15
                    
NuGet\Install-Package ReactiveLock.Core -Version 0.0.15
                    
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="ReactiveLock.Core" Version="0.0.15" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ReactiveLock.Core" Version="0.0.15" />
                    
Directory.Packages.props
<PackageReference Include="ReactiveLock.Core" />
                    
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 ReactiveLock.Core --version 0.0.15
                    
#r "nuget: ReactiveLock.Core, 0.0.15"
                    
#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 ReactiveLock.Core@0.0.15
                    
#: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=ReactiveLock.Core&version=0.0.15
                    
Install as a Cake Addin
#tool nuget:?package=ReactiveLock.Core&version=0.0.15
                    
Install as a Cake Tool

ReactiveLock

ReactiveLock is a .NET 9 library for reactive, distributed lock coordination. It allows multiple application instances to track busy/idle state and react to state changes using async handlers.

It supports both in-process and distributed synchronization. Redis is the default distributed backend.

Packages

Package Description
ReactiveLock.Core Core abstractions and in-process lock coordination
ReactiveLock.DependencyInjection Adds DI and named resolution for distributed backends
ReactiveLock.Distributed.Redis Redis-based distributed lock synchronization

Use only ReactiveLock.Core if you don't need distributed coordination.

Installation

In-process only:

dotnet add package ReactiveLock.Core

Distributed with Redis:

dotnet add package ReactiveLock.Core
dotnet add package ReactiveLock.DependencyInjection
dotnet add package ReactiveLock.Distributed.Redis

Usage

Local-only (in-process)

using MichelOliveira.Com.ReactiveLock.Core;

var state = new ReactiveLockTrackerState();
await state.SetLocalStateBlockedAsync();

var tasks = Enumerable.Range(1, 3).Select(i =>
    Task.Run(async () => {
        Console.WriteLine($"[Task {i}] Waiting...");
        await state.WaitIfBlockedAsync();
        Console.WriteLine($"[Task {i}] Proceeded.");
    })
).ToArray();

await Task.Delay(1000);
await state.SetLocalStateUnblockedAsync();
await Task.WhenAll(tasks);

Console.WriteLine("Done.");

Increment / Decrement

var state = new ReactiveLockTrackerState();
var controller = new ReactiveLockTrackerController(state);

await controller.IncrementAsync();
await Task.Delay(300);
await controller.DecrementAsync();

Distributed HTTP Client Request Counter (Redis)

Setup

builder.Services.InitializeDistributedRedisReactiveLock(Dns.GetHostName());
builder.Services.AddDistributedRedisReactiveLock("http");
builder.Services.AddTransient<CountingHandler>();

builder.Services.AddHttpClient("http", client =>
    client.BaseAddress = new Uri(builder.Configuration.GetConnectionString("http")!))
    .AddHttpMessageHandler<CountingHandler>();

var app = builder.Build();
await app.UseDistributedRedisReactiveLockAsync();

CountingHandler

public class CountingHandler : DelegatingHandler
{
    private readonly IReactiveLockTrackerController _controller;

    public CountingHandler(IReactiveLockTrackerFactory factory)
    {
        _controller = factory.GetTrackerController("http");
    }

    protected override async Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
    {
        await _controller.IncrementAsync();
        try
        {
            return await base.SendAsync(request, cancellationToken);
        }
        finally
        {
            await _controller.DecrementAsync();
        }
    }
}

Expected Behavior

  • Each HTTP request increments the "http" lock counter.
  • On response, the counter is decremented.
  • Lock state is shared across all application instances.
  • You can use the lock state to:
    • Check if any requests are active.
    • Wait for all requests to complete.

Use Case Example

var state = factory.GetTrackerState("http");

if (await state.IsBlockedAsync())
{
    Console.WriteLine("HTTP requests active.");
}

await state.WaitIfBlockedAsync();
Console.WriteLine("No active HTTP requests.");

Requirements

  • .NET 9 SDK

License

MIT © Michel Oliveira

Product Compatible and additional computed target framework versions.
.NET 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.
  • 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.

Version Downloads Last Updated
0.0.24-beta.1 0 8/28/2025
0.0.23 10 8/26/2025
0.0.23-beta.1 35 8/22/2025
0.0.22 373 8/19/2025
0.0.22-beta.13 110 8/19/2025
0.0.22-beta.10 106 8/19/2025
0.0.22-beta.9 107 8/19/2025
0.0.22-beta.8 107 8/19/2025
0.0.22-beta.7 137 8/16/2025
0.0.22-beta.6 122 8/13/2025
0.0.22-beta.5 170 8/11/2025
0.0.22-beta.4 137 8/10/2025
0.0.22-beta.3 127 8/10/2025
0.0.22-beta.2 100 8/9/2025
0.0.22-beta.1 96 8/9/2025
0.0.21 1,305 7/30/2025
0.0.20 117 7/30/2025
0.0.19 138 7/29/2025
0.0.17 118 7/29/2025
0.0.16 119 7/29/2025
0.0.15 179 7/26/2025
0.0.14 144 7/26/2025
0.0.13 150 7/26/2025
0.0.12 209 7/26/2025
0.0.11 281 7/25/2025
0.0.7 309 7/25/2025
0.0.6 317 7/25/2025
0.0.5 330 7/25/2025