MemoizR.StructuredConcurrency 0.1.6

dotnet add package MemoizR.StructuredConcurrency --version 0.1.6                
NuGet\Install-Package MemoizR.StructuredConcurrency -Version 0.1.6                
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="MemoizR.StructuredConcurrency" Version="0.1.6" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add MemoizR.StructuredConcurrency --version 0.1.6                
#r "nuget: MemoizR.StructuredConcurrency, 0.1.6"                
#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.
// Install MemoizR.StructuredConcurrency as a Cake Addin
#addin nuget:?package=MemoizR.StructuredConcurrency&version=0.1.6

// Install MemoizR.StructuredConcurrency as a Cake Tool
#tool nuget:?package=MemoizR.StructuredConcurrency&version=0.1.6                

MemoizR: Simplifying Concurrent State in .NET

"The world is still short on languages that deal super elegantly and inherently and intuitively with concurrency" Mads Torgersen Lead Designer of C# (https://www.youtube.com/watch?v=Nuw3afaXLUc&t=4402s)

MemoizR is a powerful library that simplifies concurrent state management in .NET. It provides a performant and thread-safe way to handle complex state synchronization across multiple threads, making it ideal for a wide range of applications.

Key Features

  • Dynamic Lazy Memoization: Calculate values only when needed, avoiding unnecessary computations and optimizing performance.
  • Declarative Structured Concurrency: Easily manage complex concurrency scenarios with straightforward configuration, effortless maintenance, robust error handling, and seamless cancellation.
  • Dependency Graph: Automatically track dependencies between your data, ensuring that only necessary computations are performed.
  • Automatic Synchronization: Work with shared state without the hassle of manual synchronization.
  • Performance Optimization: Benefit from memoization for read-heavy scenarios and lazy evaluation for write-heavy scenarios.

Benefits

  • Simplicity: MemoizR offers a more intuitive and manageable approach to concurrency compared to traditional async/await patterns.
  • Scalability: The concurrency model can be extended to distributed setups, similar to the actor model.
  • Maintainability: MemoizR helps you write cleaner and more maintainable code, especially when dealing with complex concurrent state.
  • Performance: Optimize performance for both read-heavy and write-heavy scenarios.

Inspiration

MemoizR draws inspiration from various sources:

  • Dynamic Lazy Memoization: Solid and Reactively
  • Structured Concurrency: Principles for well-structured concurrent code.

Usage

Basic Memoization

var f = new MemoFactory();
var v1 = f.CreateSignal(1);
var m1 = f.CreateMemoizR(async() => await v1.Get());
var m2 = f.CreateMemoizR(async() => await v1.Get() * 2);
var m3 = f.CreateMemoizR(async() => await m1.Get() + await m2.Get());
// Get Values
await m3.Get(); // Calculates m1 + 2 * m1 => (1 + 2 * 1) = 3
// Change
await v1.Set(2); // Setting v1 does not trigger the evaluation of the graph
await m3.Get(); // Calculates m1 + 2 * m1 => (1 + 2 * 2) = 6
await m3.Get(); // No operation, result remains 6

await v1.Set(3); // Setting v1 does not trigger the evaluation of the graph
await v1.Set(2); // Setting v1 does not trigger the evaluation of the graph
await m3.Get(); // No operation, result remains 6 (because the last time the graph was evaluated, v1 was already 2)

MemoizR can also handle scenarios where the graph is not stable at runtime, making it adaptable to changing dependencies.

var m3 = f.CreateMemoizR(async() => await v1.Get() ? await m1.Get() : await m2.Get());

Declarative Structured Concurrency

var f = new MemoFactory("DSC");

var child1 = f.CreateConcurrentMapReduce(
    async c =>
    {
        await Task.Delay(3000, c.Token);
        return 3;
    });

// all tasks get canceled if one fails
var c1 = f.CreateConcurrentMapReduce(
    async _ =>
    {
        await child1.Get();

        // Any group work can kick off other group work.
        await Task.WhenAll(Enumerable.Range(1, 10)
            .Select(x => f.CreateConcurrentMapReduce(
                async c =>
                {
                    await Task.Delay(3000, c.Token);
                    return x;
                }).Get()));
        
        return 4;
    });

var x = await c1.Get();

Get Started

Start using MemoizR to simplify and optimize concurrency management in your .NET applications.

Try it out!

Experiment with MemoizR online: https://dotnetfiddle.net/Widget/EWtptc

Example From: Khalid Abuhakmeh

Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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.1.6 80 11/27/2024
0.1.5 78 11/17/2024
0.1.4 116 5/25/2024
0.1.3 125 5/7/2024
0.1.2 127 5/6/2024
0.1.1 95 5/1/2024
0.1.1-rc.11 68 4/29/2024
0.1.1-rc.10 69 4/23/2024
0.1.1-rc.9 62 4/18/2024
0.1.1-rc.8 67 4/13/2024
0.1.1-rc.7 63 4/11/2024
0.1.1-rc.6 59 4/10/2024
0.1.1-rc.5 61 4/4/2024
0.1.1-rc.4 58 4/1/2024
0.1.1-rc.3 61 3/24/2024
0.1.1-rc.2 63 2/17/2024
0.1.1-rc.1 113 1/4/2024
0.1.0-rc9 176 11/6/2023
0.1.0-rc8 130 10/26/2023
0.1.0-rc7 115 10/24/2023
0.1.0-rc6 122 10/21/2023
0.1.0-rc5 109 10/19/2023
0.1.0-rc4 116 10/14/2023
0.1.0-rc3 110 10/13/2023
0.1.0-rc2 117 10/11/2023
0.1.0-rc10 98 11/12/2023
0.1.0-rc1 107 10/10/2023
0.1.0-rc.11 82 1/4/2024
0.1.0-alpha2 110 10/6/2023
0.1.0-alpha1 114 10/6/2023