MemoizR 0.1.6

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

// Install MemoizR as a Cake Tool
#tool nuget:?package=MemoizR&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.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on MemoizR:

Package Downloads
MemoizR.Reactive

Package Description

MemoizR.StructuredConcurrency

Package Description

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
0.1.6 97 11/27/2024
0.1.5 100 11/17/2024
0.1.4 137 5/25/2024
0.1.3 126 5/7/2024
0.1.2 138 5/6/2024
0.1.1 93 5/1/2024
0.1.1-rc.11 67 4/29/2024
0.1.1-rc.10 66 4/23/2024
0.1.1-rc.9 62 4/18/2024
0.1.1-rc.8 69 4/13/2024
0.1.1-rc.7 65 4/11/2024
0.1.1-rc.6 64 4/10/2024
0.1.1-rc.5 63 4/4/2024
0.1.1-rc.4 60 4/1/2024
0.1.1-rc.3 76 3/24/2024
0.1.1-rc.2 68 2/17/2024
0.1.1-rc.1 172 1/4/2024
0.1.0-rc9 208 11/6/2023
0.1.0-rc8 169 10/26/2023
0.1.0-rc7 145 10/24/2023
0.1.0-rc6 186 10/21/2023
0.1.0-rc5 133 10/19/2023
0.1.0-rc4 155 10/14/2023
0.1.0-rc3 146 10/13/2023
0.1.0-rc2 142 10/11/2023
0.1.0-rc10 127 11/12/2023
0.1.0-rc1 141 10/10/2023
0.1.0-rc.11 76 1/4/2024
0.1.0-alpha2 148 10/6/2023
0.1.0-alpha1 130 10/6/2023
0.0.4-rc4 148 9/24/2023
0.0.4-rc3 126 9/23/2023
0.0.4-rc2 126 9/23/2023
0.0.4-rc1 125 9/22/2023
0.0.4-beta1 126 9/21/2023
0.0.4-alpha1 123 9/19/2023
0.0.3-beta-1 114 9/15/2023
0.0.2-rc4 101 8/30/2023
0.0.2-rc3 112 8/30/2023
0.0.2-rc2 113 8/30/2023
0.0.2-rc1 114 8/30/2023
0.0.2-beta2 118 8/30/2023
0.0.2-beta1 125 8/29/2023
0.0.1-beta1 112 8/28/2023
0.0.1-alpha2 119 8/28/2023
0.0.1-alpha1 113 8/27/2023