CryptoHives.Foundation.Threading
0.6.21
dotnet add package CryptoHives.Foundation.Threading --version 0.6.21
NuGet\Install-Package CryptoHives.Foundation.Threading -Version 0.6.21
<PackageReference Include="CryptoHives.Foundation.Threading" Version="0.6.21" />
<PackageVersion Include="CryptoHives.Foundation.Threading" Version="0.6.21" />
<PackageReference Include="CryptoHives.Foundation.Threading" />
paket add CryptoHives.Foundation.Threading --version 0.6.21
#r "nuget: CryptoHives.Foundation.Threading, 0.6.21"
#:package CryptoHives.Foundation.Threading@0.6.21
#addin nuget:?package=CryptoHives.Foundation.Threading&version=0.6.21
#tool nuget:?package=CryptoHives.Foundation.Threading&version=0.6.21
CryptoHives Open Source Initiative 🐝
An open, community-driven collection of cryptography and performance libraries for the .NET ecosystem, maintained by The Keepers of the CryptoHives.
CryptoHives.Foundation.Threading
Pooled async synchronization primitives for .NET, built to keep Task and TaskCompletionSource<T> allocations off the hot path.
Classes
Synchronization Primitives
Namespace: CryptoHives.Foundation.Threading.Async.Pooled
| Class | Description |
|---|---|
| AsyncLock | Pooled async mutual exclusion lock |
| AsyncAutoResetEvent | Pooled async auto-reset event (one waiter per signal) |
| AsyncManualResetEvent | Pooled async manual-reset event (all waiters per signal) |
| AsyncSemaphore | Pooled async semaphore with configurable permit count |
| AsyncCountdownEvent | Pooled async countdown event (signals when count reaches zero) |
| AsyncBarrier | Pooled async barrier (synchronizes multiple participants) |
| AsyncReaderWriterLock | Pooled async reader-writer lock (multiple readers or single writer) |
All primitives are backed by ObjectPool<T> and return ValueTask<T>, which keeps per-operation allocations out of high-throughput code paths.
Pooling Support Classes
Namespace: CryptoHives.Foundation.Threading.Pools
| Class | Description | Namespace |
|---|---|---|
IGetPooledManualResetValueTaskSource<T> |
Interface for obtaining pooled IValueTaskSource<T> implementations (providers return PooledManualResetValueTaskSource<T> instances) |
|
ManualResetValueTaskSource<T> |
Abstract base for pooled IValueTaskSource<T> implementations |
|
PooledManualResetValueTaskSource<T> |
Pooled IValueTaskSource<T> implementation with automatic pool return |
|
LocalManualResetValueTaskSource<T> |
Object-local IValueTaskSource<T> without pool integration |
|
PooledValueTaskSourceObjectPolicy<T> |
Object pool policy for PooledManualResetValueTaskSource<T> |
|
ValueTaskSourceObjectPool<T> |
Specialized provider that implements IGetPooledManualResetValueTaskSource<T> and returns pooled task sources |
|
ValueTaskSourceObjectPools |
Static helper with shared pool instances and constants |
Note: This package no longer bundles CryptoHives.Foundation.Threading.Analyzers automatically. Install it separately if you want the Roslyn analyzers alongside the Threading library.
Key Features
- Pooled primitives — synchronization objects backed by
Microsoft.Extensions.ObjectPool ValueTask-based APIs — minimal to no allocations thanks to object poolingCancellationTokensupport — full cancellation across all primitives, allocation-free on modern .NETConfigureAwaitsupport — works naturally with.ConfigureAwait(false)in library code- Timeouts — every lock acquisition method accepts a timeout; a timed-out wait throws
TimeoutException, a cancelled one throwsOperationCanceledException - Configurable continuations — control whether continuations run synchronously or asynchronously
- Custom pools — supply your own
IGetPooledManualResetValueTaskSource<T>(orObjectPool<T>) for fine-grained control - Drop-in replacement — swap the namespace, keep the same
using-based patterns - Optional analyzers — ValueTask misuse caught at compile time via the separate
Threading.Analyzerspackage
Installation
dotnet add package CryptoHives.Foundation.Threading
Quick Examples
Mutual Exclusion — AsyncLock
using CryptoHives.Foundation.Threading.Async.Pooled;
private readonly AsyncLock _lock = new();
public async Task DoWorkAsync(CancellationToken ct)
{
using (await _lock.LockAsync(ct).ConfigureAwait(false))
{
// Critical section — only one task at a time
await ModifySharedStateAsync().ConfigureAwait(false);
}
}
Producer-Consumer — AsyncAutoResetEvent
private readonly AsyncAutoResetEvent _itemReady = new(initialState: false);
private readonly Queue<Item> _queue = new();
// Producer
public void Enqueue(Item item)
{
_queue.Enqueue(item);
_itemReady.Set(); // Releases exactly one waiter
}
// Consumer
public async Task<Item> DequeueAsync(CancellationToken ct)
{
await _itemReady.WaitAsync(ct).ConfigureAwait(false);
return _queue.Dequeue();
}
Broadcast — AsyncManualResetEvent
private readonly AsyncManualResetEvent _ready = new(initialState: false);
public async Task InitializeAsync()
{
await LoadConfigurationAsync().ConfigureAwait(false);
_ready.Set(); // All waiters are released at once
}
public async Task UseServiceAsync(CancellationToken ct)
{
await _ready.WaitAsync(ct).ConfigureAwait(false);
// Service is initialized
}
Bounded Concurrency — AsyncSemaphore
private readonly AsyncSemaphore _semaphore = new(initialCount: 4);
public async Task FetchAsync(CancellationToken ct)
{
await _semaphore.WaitAsync(ct).ConfigureAwait(false);
try
{
await CallExternalServiceAsync().ConfigureAwait(false);
}
finally
{
_semaphore.Release();
}
}
Read-Write Separation — AsyncReaderWriterLock
private readonly AsyncReaderWriterLock _rwLock = new();
public async Task<Data> ReadAsync(CancellationToken ct)
{
using (await _rwLock.ReaderLockAsync(ct).ConfigureAwait(false))
return _cache.Get();
}
public async Task WriteAsync(Data data, CancellationToken ct)
{
using (await _rwLock.WriterLockAsync(ct).ConfigureAwait(false))
_cache.Set(data);
}
Custom Pool
using CryptoHives.Foundation.Threading.Pools;
var policy = new PooledValueTaskSourceObjectPolicy<bool>();
var pool = new ValueTaskSourceObjectPool<bool>(policy, maximumRetained: 64);
var evt = new AsyncAutoResetEvent(
initialState: false,
runContinuationAsynchronously: true,
pool: pool);
ValueTask Contract
- Await a
ValueTaskexactly once. A secondawaitorAsTask()call may throwInvalidOperationException. - Avoid calling
AsTask()before the primitive signals. WithRunContinuationsAsynchronously=true(the default), storing the result ofAsTask()too early causes a severe performance hit. Await theValueTaskdirectly wherever you can. - Always await or discard a waiter. If it's left unconsumed, the underlying
IValueTaskSourcenever makes it back to the pool.
The bundled Threading.Analyzers package enforces these rules at compile time.
Documentation
| Resource | Link |
|---|---|
| Full package documentation | cryptohives.github.io/Foundation/packages/threading |
| API reference | cryptohives.github.io/Foundation/api |
| Benchmarks | cryptohives.github.io/Foundation/packages/threading/benchmarks |
| Threading.Analyzers | cryptohives.github.io/Foundation/packages/threading.analyzers |
| Source repository | github.com/CryptoHives/Foundation |
Security Policy
If you discover a vulnerability, please don't open a public issue — follow the process on the CryptoHives Security Page instead.
License
MIT — © 2026 The Keepers of the CryptoHives
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. 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 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. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 is compatible. |
| .NET Framework | net461 was computed. net462 is compatible. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.6.2
- Microsoft.Bcl.AsyncInterfaces (>= 10.0.9)
- Microsoft.Bcl.HashCode (>= 6.0.0)
- Microsoft.Bcl.TimeProvider (>= 10.0.9)
- Microsoft.Extensions.ObjectPool (>= 10.0.9)
- System.Memory (>= 4.6.3)
- System.Threading.Tasks.Extensions (>= 4.6.3)
-
.NETStandard 2.0
- Microsoft.Bcl.AsyncInterfaces (>= 10.0.9)
- Microsoft.Bcl.HashCode (>= 6.0.0)
- Microsoft.Bcl.TimeProvider (>= 10.0.9)
- Microsoft.Extensions.ObjectPool (>= 10.0.9)
- System.Memory (>= 4.6.3)
- System.Threading.Tasks.Extensions (>= 4.6.3)
-
.NETStandard 2.1
- Microsoft.Bcl.AsyncInterfaces (>= 10.0.9)
- Microsoft.Bcl.TimeProvider (>= 10.0.9)
- Microsoft.Extensions.ObjectPool (>= 10.0.9)
-
net10.0
- Microsoft.Extensions.ObjectPool (>= 10.0.9)
-
net8.0
- Microsoft.Extensions.ObjectPool (>= 10.0.9)
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.6.21 | 53 | 7/4/2026 |
| 0.5.34-preview | 581 | 6/2/2026 |
| 0.5.21-preview | 117 | 5/2/2026 |
| 0.5.13-preview | 68 | 4/2/2026 |
| 0.4.21-preview | 77 | 3/1/2026 |
| 0.4.11-preview | 83 | 2/14/2026 |
| 0.3.19-preview | 82 | 1/26/2026 |
| 0.2.43-preview | 85 | 1/9/2026 |
| 0.2.33-preview | 429 | 12/9/2025 |
| 0.2.30-preview | 343 | 12/8/2025 |
| 0.2.28-preview | 277 | 12/7/2025 |
| 0.2.26-preview | 218 | 12/6/2025 |
| 0.2.22-preview | 566 | 12/1/2025 |
| 0.2.17-preview | 179 | 11/23/2025 |
| 0.2.13-preview | 404 | 11/20/2025 |
| 0.2.11-preview | 992 | 11/19/2025 |