ZeroAlloc.AsyncEvents
1.1.11
dotnet add package ZeroAlloc.AsyncEvents --version 1.1.11
NuGet\Install-Package ZeroAlloc.AsyncEvents -Version 1.1.11
<PackageReference Include="ZeroAlloc.AsyncEvents" Version="1.1.11" />
<PackageVersion Include="ZeroAlloc.AsyncEvents" Version="1.1.11" />
<PackageReference Include="ZeroAlloc.AsyncEvents" />
paket add ZeroAlloc.AsyncEvents --version 1.1.11
#r "nuget: ZeroAlloc.AsyncEvents, 1.1.11"
#:package ZeroAlloc.AsyncEvents@1.1.11
#addin nuget:?package=ZeroAlloc.AsyncEvents&version=1.1.11
#tool nuget:?package=ZeroAlloc.AsyncEvents&version=1.1.11
ZeroAlloc.AsyncEvents
Async events for .NET that you can actually await: a drop-in replacement for EventHandler<T> and Func<T, Task> + Task.WhenAll, with no allocations per invocation when handlers complete synchronously.
Why ZeroAlloc.AsyncEvents
- 0 B per invocation. Raising an event whose handlers complete synchronously allocates nothing, in parallel and in sequential mode; tests assert it on net8.0 and net10.0. Naive async allocates 280–288 B per call.
- More than 10× faster than
Task.WhenAllfan-out, and faster than a plain synchronous multicast delegate, measured in the same run. - Real
asyncsemantics. Handlers returnValueTask, receive aCancellationToken, and run in parallel or in registration order. Exceptions reach the caller instead of vanishing in anasync void. - Works under NativeAOT and trimming. No reflection; CI publishes and runs a NativeAOT sample on every build.
Install
dotnet add package ZeroAlloc.AsyncEvents
Quick start
using ZeroAlloc.AsyncEvents;
var orders = new OrderService();
orders.OrderPlaced += async (order, ct) =>
{
await Task.Delay(10, ct); // e.g. send a confirmation email
Console.WriteLine($"Emailed order {order.Id}");
};
orders.OrderPlaced += (order, ct) =>
{
Console.WriteLine($"Audited order {order.Id}"); // completes synchronously
return ValueTask.CompletedTask;
};
await orders.PlaceAsync(new OrderPlaced(42));
public sealed record OrderPlaced(int Id);
public partial class OrderService
{
// The generator writes `public event AsyncEvent<OrderPlaced> OrderPlaced` for this field.
[AsyncEvent]
private AsyncEventHandler<OrderPlaced> _orderPlaced = new(InvokeMode.Parallel);
public ValueTask PlaceAsync(OrderPlaced order, CancellationToken ct = default)
=> _orderPlaced.InvokeAsync(order, ct);
}
PlaceAsync returns once both handlers have finished. Subscribers use the familiar += and -=.
What you get
- Parallel or sequential dispatch, chosen per field and overridable per call. Invoke modes
- Cancelable events. A handler sets
Canceland the remaining handlers are skipped, for validation and veto pipelines. Cancelable events - Generated
eventaccessors with[AsyncEvent]on a field or on the whole class. Mistakes are reported at compile time. Source generator, diagnostics - Lock-free, thread-safe subscription. Registering and unregistering never takes a lock.
- Broad reach:
netstandard2.0,netstandard2.1,net8.0andnet10.0. - Async property and collection notifications, the async
INotifyPropertyChangedfamily, come from ZeroAlloc.Notify, which builds on this package.
Performance
Ten handlers, each returning a completed task, invoked once. net10.0, BenchmarkDotNet, same run; the ratio is against a synchronous multicast delegate. Allocations are exact; speed is a same-run ratio.
| Method | Ratio | Allocated |
|---|---|---|
EventHandler<T>, sync multicast |
1.00 | 0 B |
Func<T, Task> + Task.WhenAll |
11.93 | 280 B |
| ZeroAlloc.AsyncEvents, parallel | 0.44 | 0 B |
| ZeroAlloc.AsyncEvents, sequential | 0.61 | 0 B |
Full results for net8.0 and net10.0, methodology and allocation notes: docs/performance.md.
Learn more
- Documentation: asyncevents.zeroalloc.net
- Related packages: ZeroAlloc.Notify for async property and collection notifications, and the rest of the ZeroAlloc family
- Contributing: issues and pull requests are welcome on GitHub
- License: MIT
| 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. |
|
|
ZeroAlloc.EventSourcing
Source-generated event-sourced aggregates for .NET. Zero-allocation event dispatch, AOT-safe. |
|
|
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. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.1.11 | 205 | 10/18/2026 |
| 1.1.10 | 2,502 | 10/16/2026 |
| 1.1.9 | 1,208 | 10/15/2026 |
| 1.1.8 | 2,651 | 10/11/2026 |
| 1.1.7 | 12,844 | 9/30/2026 |
| 1.1.6 | 3,120 | 9/28/2026 |
| 1.1.5 | 1,143 | 9/27/2026 |
| 1.1.4 | 11,230 | 9/20/2026 |
| 1.1.3 | 4,406 | 9/19/2026 |
| 1.1.2 | 19,166 | 5/28/2026 |
| 1.1.1 | 922 | 5/12/2026 |
| 1.1.0 | 805 | 5/1/2026 |
| 1.0.3 | 1,441 | 5/1/2026 |
| 1.0.2 | 1,131 | 4/29/2026 |
| 1.0.1 | 1,146 | 4/28/2026 |
| 1.0.0 | 1,426 | 3/27/2026 |
| 0.3.0 | 140 | 4/1/2026 |
| 0.2.1 | 290 | 3/27/2026 |