ZeroAlloc.AsyncEvents
1.1.8
dotnet add package ZeroAlloc.AsyncEvents --version 1.1.8
NuGet\Install-Package ZeroAlloc.AsyncEvents -Version 1.1.8
<PackageReference Include="ZeroAlloc.AsyncEvents" Version="1.1.8" />
<PackageVersion Include="ZeroAlloc.AsyncEvents" Version="1.1.8" />
<PackageReference Include="ZeroAlloc.AsyncEvents" />
paket add ZeroAlloc.AsyncEvents --version 1.1.8
#r "nuget: ZeroAlloc.AsyncEvents, 1.1.8"
#:package ZeroAlloc.AsyncEvents@1.1.8
#addin nuget:?package=ZeroAlloc.AsyncEvents&version=1.1.8
#tool nuget:?package=ZeroAlloc.AsyncEvents&version=1.1.8
ZeroAlloc.AsyncEvents
Zero-allocation async event handler structs for .NET. Lock-free registration, ValueTask invocation, ArrayPool parallel dispatch.
Key Characteristics
- Lock-free registration — CAS-loop register/unregister, no locks
- ValueTask throughout — no
Taskallocations on hot paths - ArrayPool parallel dispatch — handlers that complete synchronously cost nothing; only unfinished or failed ones go to a rented array and
WhenAll - Multi-target —
netstandard2.0,netstandard2.1,net8.0,net10.0 - AOT compatible
Performance
10 handlers registered, invoked once, each returning a completed task. Compared against EventHandler<T> (sync multicast, baseline) and naive async (Func<string, Task> + Task.WhenAll). BenchmarkDotNet v0.15.8, X64 RyuJIT, Intel Core i9-12900HK, in-process toolchain.
net8.0
| Method | Mean | Error | StdDev | Ratio | Allocated |
|---|---|---|---|---|---|
| Sync_MulticastDelegate_10Handlers | 57.81 ns | 1.246 ns | 3.675 ns | 1.00 | — |
| NaiveAsync_TaskWhenAll_10Handlers | 476.80 ns | 9.552 ns | 12.080 ns | 8.28x | 288 B |
| ZeroAlloc_Parallel_10Handlers | 35.52 ns | 1.271 ns | 3.728 ns | 0.62x | — |
| ZeroAlloc_Sequential_10Handlers | 47.75 ns | 0.350 ns | 0.328 ns | 0.83x | — |
net10.0
| Method | Mean | Error | StdDev | Ratio | Allocated |
|---|---|---|---|---|---|
| Sync_MulticastDelegate_10Handlers | 40.69 ns | 0.501 ns | 0.444 ns | 1.00 | — |
| NaiveAsync_TaskWhenAll_10Handlers | 440.47 ns | 20.112 ns | 59.300 ns | 10.83x | 280 B |
| ZeroAlloc_Parallel_10Handlers | 18.31 ns | 1.093 ns | 3.207 ns | 0.45x | — |
| ZeroAlloc_Sequential_10Handlers | 29.60 ns | 1.067 ns | 3.147 ns | 0.73x | — |
Both ZeroAlloc modes allocate nothing on either target when handlers complete synchronously, and both are faster than a sync multicast delegate. Parallel mode is more than 10× faster than naive async, which allocates 280–288 B per call.
Installation
dotnet add package ZeroAlloc.AsyncEvents
Quick Start
// Declare the backing field
private AsyncEventHandler<OrderPlacedArgs> _orderPlaced = new(InvokeMode.Parallel);
// Expose as a C# event — or use [AsyncEvent] to let the source generator do this
public event AsyncEvent<OrderPlacedArgs> OrderPlaced
{
add => _orderPlaced.Register(value);
remove => _orderPlaced.Unregister(value);
}
// Invoke
await _orderPlaced.InvokeAsync(new OrderPlacedArgs(orderId), cancellationToken);
Source Generator
Annotate fields with [AsyncEvent] on a partial class and the generator writes the event property for you:
public partial class OrderService
{
[AsyncEvent(InvokeMode.Parallel)]
private AsyncEventHandler<OrderPlacedArgs> _orderPlaced = new(InvokeMode.Parallel);
}
Generates:
public event AsyncEvent<OrderPlacedArgs> OrderPlaced
{
add => _orderPlaced.Register(value);
remove => _orderPlaced.Unregister(value);
}
Apply [AsyncEvent] to the class instead to cover all AsyncEventHandler<TArgs> fields at once. See Source Generator for details.
Async INotify* Interfaces
Async INotify* interfaces and event args are provided by ZeroAlloc.Notify, which builds on this package.
Design Philosophy
AsyncEventHandler<TArgs> is a struct wrapping a State reference — copy semantics are intentional and match how event fields work in C#. Use it as a private field and expose Register/Unregister methods, or use the +=/-= operators directly.
CancellationToken is threaded through every call site — handlers opt into cooperative cancellation at the delegate boundary. Sequential mode respects cancellation between handler invocations; parallel mode checks before dispatch.
See docs/ for full documentation.
| 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 was computed. 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. |
-
.NETStandard 2.0
- System.Buffers (>= 4.6.1)
- System.Threading.Tasks.Extensions (>= 4.6.3)
-
.NETStandard 2.1
- No dependencies.
-
net10.0
- No dependencies.
-
net8.0
- No dependencies.
NuGet packages (17)
Showing the top 5 NuGet packages that depend on ZeroAlloc.AsyncEvents:
| Package | Downloads |
|---|---|
|
AdoNet.Async.DataSet
Async DataSet and DataTable for ADO.NET (System.Data). Includes AsyncDataTable, AsyncDataSet, and AsyncDataAdapter. |
|
|
AI.Sentinel
Security monitoring middleware for IChatClient — prompt injection, hallucination, and operational anomaly detection with an intervention engine. |
|
|
Thalos.NET
Thalos.NET agent runtime on Microsoft Agent Framework: agent factory, tool catalog with authorization, session state machine, in-memory session store. |
|
|
BlazorNative.Core
Core contracts for BlazorNative: shell bridge and interop abstractions, the INavigationManager contract, and the DI-facing primitives shared by the renderer, HTTP bridge, and component library. |
|
|
BlazorNative.Renderer
The BlazorNative renderer: drives Blazor's RenderTree diffing into a native widget tree and emits binary UI patch frames for platform shells. NativeAOT/trim-compatible. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.1.8 | 0 | 10/11/2026 |
| 1.1.7 | 4,693 | 9/30/2026 |
| 1.1.6 | 3,114 | 9/28/2026 |
| 1.1.5 | 1,135 | 9/27/2026 |
| 1.1.4 | 11,179 | 9/20/2026 |
| 1.1.3 | 3,247 | 9/19/2026 |
| 1.1.2 | 19,164 | 5/28/2026 |
| 1.1.1 | 921 | 5/12/2026 |
| 1.1.0 | 804 | 5/1/2026 |
| 1.0.3 | 1,436 | 5/1/2026 |
| 1.0.2 | 1,130 | 4/29/2026 |
| 1.0.1 | 1,145 | 4/28/2026 |
| 1.0.0 | 1,423 | 3/27/2026 |
| 0.3.0 | 139 | 4/1/2026 |
| 0.2.1 | 288 | 3/27/2026 |