EonaCat.AsyncFlowKit
1.0.0
Prefix Reserved
dotnet add package EonaCat.AsyncFlowKit --version 1.0.0
NuGet\Install-Package EonaCat.AsyncFlowKit -Version 1.0.0
<PackageReference Include="EonaCat.AsyncFlowKit" Version="1.0.0" />
<PackageVersion Include="EonaCat.AsyncFlowKit" Version="1.0.0" />
<PackageReference Include="EonaCat.AsyncFlowKit" />
paket add EonaCat.AsyncFlowKit --version 1.0.0
#r "nuget: EonaCat.AsyncFlowKit, 1.0.0"
#:package EonaCat.AsyncFlowKit@1.0.0
#addin nuget:?package=EonaCat.AsyncFlowKit&version=1.0.0
#tool nuget:?package=EonaCat.AsyncFlowKit&version=1.0.0
EonaCat.AsyncFlowKit
A lightweight .NET library providing async synchronization primitives and concurrency utilities.
EonaCat.AsyncFlowKit is designed for modern asynchronous applications where you need safe coordination between tasks, cancellation handling, and lock-free state updates.
Features
- Async-friendly synchronization primitives
- Cancellation helpers
- Lock-free concurrent state container
- No external dependencies
- Designed for high-performance async workflows
- Compatible with .NET Standard 2.0+
Supported Frameworks
- .NET Standard 2.0
- .NET Standard 2.1
- .NET 5+
- .NET 6+
- .NET 7+
- .NET 8+
Installation
Install from NuGet:
dotnet add package EonaCat.AsyncFlowKit
or:
Install-Package EonaCat.AsyncFlowKit
AsyncEvent
AsyncEvent is an asynchronous one-shot signaling primitive.
It allows tasks to wait until another part of the application signals completion.
Unlike ManualResetEvent, it does not block threads.
Basic Usage
using EonaCat.AsyncFlowKit;
var signal = new AsyncEvent();
var worker = Task.Run(async () =>
{
Console.WriteLine("Waiting...");
await signal.WaitAsync();
Console.WriteLine("Signal received");
});
await Task.Delay(1000);
signal.Set();
await worker;
Output:
Waiting...
Signal received
Cancellation
Waiting supports cancellation tokens:
var signal = new AsyncEvent();
using var cts = new CancellationTokenSource();
var task = signal.WaitAsync(cts.Token);
cts.Cancel();
await task;
If cancelled, the wait operation completes through cancellation.
Multiple Waiters
Multiple tasks can wait for the same signal:
var signal = new AsyncEvent();
var tasks = Enumerable.Range(0, 5)
.Select(async i =>
{
await signal.WaitAsync();
Console.WriteLine($"Worker {i} released");
});
await Task.Delay(500);
signal.Set();
await Task.WhenAll(tasks);
ConcurrentState<T>
ConcurrentState<T> provides thread-safe state updates without traditional locks.
It is useful for maintaining shared state between async operations.
Creating State
using EonaCat.AsyncFlowKit;
var counter = new ConcurrentState<int>(0);
Reading State
var value = counter.Read();
Console.WriteLine(value);
Updating State
counter.Update(x => x + 1);
Example:
var state = new ConcurrentState<int>(0);
Parallel.For(0, 1000, _ =>
{
state.Update(x => x + 1);
});
Console.WriteLine(state.Read());
Result:
1000
Complex State
Works with objects:
class UserStats
{
public int Logins { get; set; }
}
var stats = new ConcurrentState<UserStats>(
new UserStats());
stats.Update(current =>
{
return new UserStats
{
Logins = current.Logins + 1
};
});
CancellationExtensions
Extension methods for working with cancellation tokens.
CancelAfterAsync
Waits until either:
- cancellation happens
- timeout expires
Example:
using EonaCat.AsyncFlowKit;
var cts = new CancellationTokenSource();
var task =
cts.Token.CancelAfterAsync(
TimeSpan.FromSeconds(5));
cts.Cancel();
await task;
Console.WriteLine("Finished");
Timeout Cancellation
Create a linked cancellation source with timeout:
var timeout =
token.CreateLinkedTimeout(
TimeSpan.FromSeconds(10));
await SomeOperationAsync(timeout.Token);
The operation will cancel when:
- the original token cancels
- timeout expires
Example: Async Worker Queue
var wakeup = new AsyncEvent();
var worker = Task.Run(async () =>
{
while(true)
{
await wakeup.WaitAsync();
Console.WriteLine(
"Processing work");
}
});
while(true)
{
Console.WriteLine(
"New work available");
wakeup.Set();
await Task.Delay(1000);
}
Example: Shared Configuration State
class Configuration
{
public string Mode { get; set; }
}
var config =
new ConcurrentState<Configuration>(
new Configuration
{
Mode = "Development"
});
config.Update(current =>
{
return new Configuration
{
Mode = "Production"
};
});
Console.WriteLine(
config.Read().Mode);
Thread Safety
AsyncEvent
- Thread-safe
- Multiple producers supported
- Multiple async consumers supported
ConcurrentState<T>
- Atomic updates
- Lock-free for reference types
- Safe for concurrent reads and updates
CancellationExtensions
- Safe for concurrent cancellation
Design Goals
EonaCat.AsyncFlowKit focuses on:
- Simple APIs
- Correct async behavior
- Avoiding blocked threads
- Minimal allocations
- Compatibility with older .NET runtimes
When To Use
Good fit:
- Background workers
- Task pipelines
- Async services
- Message processing
- Rate limiting
- Shared application state
Not intended for:
- CPU synchronization
- Replacing all locking primitives
- Long-running blocking operations
License
MIT License
Copyright (c) EonaCat (Jeroen Saey)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files, to deal in the Software without restriction.
| 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 was computed. 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 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. |
| .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 was computed. |
| .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
- Microsoft.Bcl.AsyncInterfaces (>= 8.0.0)
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 |
|---|---|---|
| 1.0.0 | 157 | 6/16/2026 |