Soenneker.Asyncs.Locks
4.0.10
Prefix Reserved
dotnet add package Soenneker.Asyncs.Locks --version 4.0.10
NuGet\Install-Package Soenneker.Asyncs.Locks -Version 4.0.10
<PackageReference Include="Soenneker.Asyncs.Locks" Version="4.0.10" />
<PackageVersion Include="Soenneker.Asyncs.Locks" Version="4.0.10" />
<PackageReference Include="Soenneker.Asyncs.Locks" />
paket add Soenneker.Asyncs.Locks --version 4.0.10
#r "nuget: Soenneker.Asyncs.Locks, 4.0.10"
#:package Soenneker.Asyncs.Locks@4.0.10
#addin nuget:?package=Soenneker.Asyncs.Locks&version=4.0.10
#tool nuget:?package=Soenneker.Asyncs.Locks&version=4.0.10
Soenneker.Asyncs.Locks
The fastest .NET async lock
This library provides a single primitive: AsyncLock.
Design goal
The goal of AsyncLock is to provide the fastest possible correct mutex for real world .NET systems.
Specifically, it is designed to:
- make the uncontended case as close to a single atomic operation as possible
- avoid allocations, tasks, queues, and state machines unless contention actually occurs
- support cancellation and disposal without contaminating the fast path
- allow async and synchronous code to share the same lock safely
- preserve deterministic behavior under contention
Installation
dotnet add package Soenneker.Asyncs.Locks
Usage
Async
await using (await _lock.Lock(ct))
{
// critical section
}
Sync
using (_lock.LockSync())
{
// critical section
}
Try-lock
if (_lock.TryLock(out var releaser))
{
using (releaser)
{
// critical section
}
}
Benchmarks
Async lock acquisition
| Method | Mean | Median | Allocated |
|---|---|---|---|
| Soenneker.AsyncLock | 14.53 ns | 14.51 ns | 0 B |
| SemaphoreSlim | 20.68 ns | 20.09 ns | 0 B |
| Nito.AsyncEx.AsyncLock | 62.57 ns | 60.58 ns | 320 B |
Synchronous lock acquisition
| Method | Mean | Median | Allocated |
|---|---|---|---|
| Soenneker.AsyncLock (sync) | 8.08 ns | 7.97 ns | 0 B |
| SemaphoreSlim (sync) | 22.05 ns | 21.76 ns | 0 B |
| Nito.AsyncEx.AsyncLock (sync) | 60.27 ns | 58.98 ns | 320 B |
Correctness without compromise
Cancellation-aware Supports cancellation before acquisition and while waiting for both async and sync callers. Cancelled waiters are removed immediately, never resumed, and never leaked with zero cost on the fast path.
Unified async and sync locking A single mutex is shared by async and synchronous code paths. Ordering is preserved with no adapters, wrappers, or duplicate synchronization primitives.
Safe deterministic disposal Disposal releases all waiters with
ObjectDisposedException, can be awaited, and blocks until the current owner exits without penalizing uncontended performance.
| 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.Atomics.ValueBools (>= 4.0.9)
- Soenneker.Extensions.Task (>= 4.0.111)
NuGet packages (10)
Showing the top 5 NuGet packages that depend on Soenneker.Asyncs.Locks:
| Package | Downloads |
|---|---|
|
Soenneker.Utils.AsyncSingleton
An externally initializing singleton that uses double-check asynchronous locking, with optional async and sync disposal |
|
|
Soenneker.Utils.SingletonDictionary
An externally initializing singleton dictionary that uses double-check asynchronous locking, with optional async and sync disposal |
|
|
Soenneker.Utils.BackgroundQueue
A high-performance background Task/ValueTask queue |
|
|
Soenneker.Blazor.Utils.Session
A Blazor utility for automatic navigation after JWT expiration |
|
|
Soenneker.Utils.Path
A utility library for directory path related operations |
GitHub repositories
This package is not used by any popular GitHub repositories.