Calm.Core 1.0.1

dotnet add package Calm.Core --version 1.0.1
                    
NuGet\Install-Package Calm.Core -Version 1.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Calm.Core" Version="1.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Calm.Core" Version="1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="Calm.Core" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Calm.Core --version 1.0.1
                    
#r "nuget: Calm.Core, 1.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Calm.Core@1.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Calm.Core&version=1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=Calm.Core&version=1.0.1
                    
Install as a Cake Tool

License GitHub Actions CodeQL

CALM Logo

CALM

CALM (Cooperative Async Lock-free Messaging) is a high-performance, lightweight execution engine for .NET designed to simplify concurrent programming.

💡 Motivation

Standard async/await in C# is powerful, but it doesn't automatically prevent deadlocks or race conditions. These bugs are notoriously hard to reproduce and debug.

Previously, I tried to solve this by running yield return coroutines on a single thread. While it ensured thread safety, it hit two major walls:

  1. Structural limitations: try/catch blocks didn't work across yield points.
  2. Concurrency limitations: It couldn't efficiently handle IO-bound work concurrently (interleaving).

CALM solves these challenges by running standard async methods on a single dedicated message pump.

  • Lock-free Safety: By serializing all execution, it eliminates race conditions and deadlocks.
  • Resource Efficient: No thread pool churn; no need for complex semaphore management to limit resource contention.
  • Predictable: It provides a "Calm" development experience where you focus on logic, not synchronization.

🚀 Key Features

  • Guaranteed Single-Threading: All operations within an engine instance are serialized, providing an actor-like thread-safety model.
  • Resource Efficiency: Minimizes thread pool consumption by processing all tasks on a single dedicated thread, preventing thread pool starvation even under high task volumes.
  • Deadlock Elimination: By serializing all tasks through a high-performance Channel-based message pump, it removes the need for traditional locks.
  • Role-based Messaging: Built-in support for Commands, Queries, and Events with a simple, attribute-based handler discovery.
  • DI Ready: Seamlessly integrates with Microsoft.Extensions.DependencyInjection and supports automatic handler registration from assemblies.
  • Multi-Target Support: Compatible with .NET Framework 4.7.2, .NET Standard 2.0/2.1, and .NET 8/10.

📦 Packages

Package Nuget
Calm.Core<br/>The core high-performance execution engine and messaging abstractions. NuGet
Calm.Extensions.DependencyInjection<br/>Seamless integration with Microsoft.Extensions.DependencyInjection. NuGet

📦 Installation

Install the core package via NuGet:

dotnet add package Calm.Core

If you are using Dependency Injection (recommended), install the extensions:

dotnet add package Calm.Extensions.DependencyInjection

⚡ Quick Start

1. Define your Messages

Implement ICalmCommand, ICalmQuery<T>, or ICalmEvent.

public record GreetCommand(string Name) : ICalmCommand;
public record GetVersionQuery() : ICalmQuery<string>;

2. Implement Handlers

Decorate your methods with the [CalmHandler] attribute.

public class GreetingService
{
    [CalmHandler]
    public Task HandleAsync(GreetCommand command, CancellationToken ct)
    {
        Console.WriteLine($"Hello, {command.Name}!");
        return Task.CompletedTask;
    }

    [CalmHandler]
    public Task<string> HandleAsync(GetVersionQuery query, CancellationToken ct)
    {
        return Task.FromResult("1.0.0");
    }
}

3. Setup and Execution (with DI)

var services = new ServiceCollection();

// Add CALM and register handlers from the assembly
services.AddCalm();
services.AddCalmHandlersFromAssembly(ServiceLifetime.Singleton, typeof(GreetingService).Assembly);

var provider = services.BuildServiceProvider();

// Start the engine
var calm = provider.GetRequiredService<ICalm>();
calm.Start();

// Send a command
await calm.Command.SendAsync(new GreetCommand("World"));

// Send a query
var version = await calm.Query.SendAsync(new GetVersionQuery());

⚠️ Important Safety Rules

To maintain the safety guarantees provided by CALM, please adhere to these rules:

  1. Avoid .ConfigureAwait(false): Within CALM handlers or tasks, always stay on the engine thread. Using false can leak the execution to the thread pool, leading to race conditions.
  2. Do NOT Register in Constructors: Never call Register(this) in a constructor. This leads to a "this-reference leak" where an uninitialized object is exposed to the engine. Use a Load event or an explicit initialization method instead.
  3. Always Unregister: To prevent memory leaks, ensure that instances registered with the engine are Unregister()ed or disposed of when no longer needed.

🎓 Learning Path with Samples

To help you get started with CALM, we have prepared a series of samples that guide you through its features step-by-step. You can find them in the samples directory.

Step Sample Focus Area
1 Sample01 Basics: Engine lifecycle, scheduling, and thread safety.
2 Sample02 Messaging: Commands, Queries, Events, and Role-based Messaging.
3 Sample03 Integration: .NET Generic Host and Dependency Injection.
4 Sample04 GUI: WPF integration and MVVM pattern.
5 Sample05 Robustness: Error handling, observers, and diagnostics.
6 WinForms Real-world: Practical usage with ReactiveUI and WinForms.

See the Samples README for a detailed breakdown of each sample.

📚 Documentation

For detailed guides, advanced configurations, and architectural deep-dives, please refer to our Documentation Site.

📄 License

Product 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 is compatible.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Calm.Core:

Package Downloads
Calm.Extensions.DependencyInjection

Dependency Injection extensions for CALM. Seamlessly integrates CALM execution engines and messaging services with Microsoft.Extensions.DependencyInjection.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.1 129 6/28/2026
1.0.0 172 6/2/2026