Skip to content

Instantly share code, notes, and snippets.

@cajuncoding
Last active August 4, 2020 20:48
Show Gist options
  • Save cajuncoding/e2ff490d79812c83bedfd5a77888e727 to your computer and use it in GitHub Desktop.
Save cajuncoding/e2ff490d79812c83bedfd5a77888e727 to your computer and use it in GitHub Desktop.
Super simple self-populating generic typed static caching implementation using Lazy<> & ConcurrentDictionary<>... For a full blown production ready implementation check out the LazyCacheHelpers project.
using System;
using System.Collections.Concurrent;
public class SimpleLazyCacheHelper<T> where T: class
{
private readonly ConcurrentDictionary<string, Lazy<T>> _cache = new ConcurrentDictionary<string, Lazy<T>>();
[Obsolete("This method adds existing values to the cache, but it's best to use GetOrAddToCache() to facilitate a self-populating cache (especially in a Web environment)")]
public void AddToCache(string key, T value)
{
_cache.TryAdd(key, new Lazy<T>(() => value));
}
[Obsolete("This method returns only existing values; it's best to initialize cache values via GetOrAddToCache()")]
public T GetFromCache(string key)
{
return _cache[key]?.Value;
}
/// <summary>
/// Provides a self-populating/blocking approach to the cache so that ALL Threads wait for the first thread that requested a cache key
/// to be initialized and populated into the cache. This means that they will always wait less time than if they did all the
/// work itself. Very useful for long running work (e.g. DB calls, I/O processing, etc).
/// More info. on the value fo self-populating approach is here:
/// https://www.ehcache.org/documentation/2.8/apis/constructs.html
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="valueFactory"></param>
public T GetOrAddToCache(string key, Func<T> valueFactory)
{
return _cache.GetOrAdd(key, new Lazy<T>(valueFactory))?.Value;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment