AF.Decay 1.4.0

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

// Install AF.Decay as a Cake Tool
#tool nuget:?package=AF.Decay&version=1.4.0                

C# Decay<T>

alternate text is missing from this package README image

Decay any object causing it's value to expire after a specific condition becomes true.

Things to Note

  • Conditions left unspecified in the constructor of a Decay<> object will not be applied toward the expiration policy of the decaying object.
  • ObjectExpiredException will be thrown when the value of the decaying object expires if you set throwExceptionOnExpiration to true. You can inspect the key of the Data dictionary of the exception to determine which policies caused the object to expire.

Getting Started

Suppose you have an instance called SomeObject and you want it to expire after acessing it more than five times or if it has been more than 10 seconds, whichever comes first.

var myObject = new SomeObject();

var decayingObject = new Decay<SomeObject>(myObject, 
  expireAfterCount: 5, 
  expirationDateTime: DateTimeOffset.UtcNow.AddSeconds(10), 
  throwExceptionOnExpiration: true);

myObject = decayingObject.Value; // Access the value up to 5 times within the next 10 seconds before it decays.

// 10 seconds later...

myObject = decayingObject.Value; // myObject == null

Expire After Accessing x Times

var myObject = new SomeObject();
var decayingObject = new Decay<SomeObject>(myObject, expireAfterCount: 5);
myObject = decayingObject.Value // Value will be null after accessing it five times.

Expire After Time Horizon

var myObject = new SomeObject();
var decayingObject = new Decay<SomeObject>(myObject, expirationDateTime: DateTimeOffset.UtcNow.AddSeconds(10));
myObject = decayingObject.Value // Value will be null 10 seconds from creation of the Decay<> object.

Expire On Custom Condition

Sometimes you will want to make values decay based on a custom condition. The expireOnCondition parameter allows you to define a custom function that should return true when the object is considered expired. This function will be called each time Decay<T>.Value is accessed to determine if the object should be marked expired. The expirationTime == null and currentCount == 0 (never increments) unless those policies are set when the object is created.

var myObject = new SomeObject();
var decayingObject = new Decay<SomeObject>(myObject, expireOnCondition: (DateTimeOffset? expirationTime, long currentCount) =>
{
    return true; // return true to indicate expiration
});
myObject = decayingObject.Value; // Value will be null and expired when your custom function returns true;

Factory Methods

Instantiate decaying objects with more convenient syntax when you only care about applying a single type of policy:

var decayingObject = Decay<string>.OnExpiration("123", TimeSpan.FromMinutes(30));
var decayingObject = Decay<string>.OnCount("123", 10);
var decayingObject = Decay<string>.OnCondition("123", (expirationTime, currentCount) =>
{
	return true; // on expiration
});

Combine with Lazy<T>

Perhaps you want to delay the creation of the object but also cause it to decay. Depending on how you wrap Lazy<> and Decay<> will determine their behavior.

// Delay creation of an expensive object that will expire 10 seconds after it was created.
var delayedDecayingObject = new Lazy<Decay<SomeObject>>(() => new Decay<SomeObject>(new SomeObject(), expirationDateTime: someFutureDateTime));

// The entire Lazy<> object has started to decay even though the internal SomeObject value has not been initialized yet.
// This could be useful when it's possible an expensive object should never be created if it's not used within the decaying expiration policy.
var decayingObject = new Decay<Lazy<SomeObject>>(new Lazy<SomeObject>(() => new SomeObject()), expirationDateTime: someFutureDateTime);

Sort

You can also sort a list of decaying objects into the order in which they are next to decay:

var list = new List<Decay<int>>();
// ... add some objects
list.Sort(); // Ordered by next to decay

Collections

Extension methods for managing collections of Decay<T> objects.

// Get next item closest to decay, removing expired items
var nextItem = collection.GetNextDecayingItem();

// Get next item closest to decay, preserving expired items
var nextItem = collection.GetNextDecayingItem(clearDecayedItems: false);

// Get all expired items
var expiredItems = collection.GetDecayedItems();

// Get all non-expired items  
var activeItems = collection.GetNonDecayedItems();

// Remove expired items and get count removed
int removed = collection.ClearDecayedItems();
Product Compatible and additional computed target framework versions.
.NET net5.0 is compatible.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net5.0

    • No dependencies.

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.4.0 38 12/20/2024
1.3.0 4,782 6/15/2023
1.2.0 234 6/9/2023
1.1.0 235 6/8/2023
1.0.0 361 2/28/2022