Skip to content

Troubleshooting LazyCache

Alastair Crabtree edited this page Dec 27, 2019 · 4 revisions

In-memory caching will always cache by reference to the object

LazyCache uses microsoft.extensions.caching.memory to actually cache your objects. This means that if you ask LazyCache to cache your object it will hold onto a reference to it (stopping it being garbage collected) and return the reference to the same instance of the object next time you ask for it.

If you modify something on that object outside of LazyCache then LazyCache will still return a reference to the same object, including any changes you have made to it.

To say it another way, LazyCache does not clone or copy the object you have built and cached - it just returns the same instance.

This is demonstrated in the following example:

IAppCache cache = new CachingService();

var cacheResult1 = cache.GetOrAdd("SomeLongCacheKey", () => new ExampleClass() { Message = "Hello" );

// prints 'Hello'
Console.WriteLine(cacheResult1.Message);
           
var cacheResult2 = cache.GetOrAdd("SomeLongCacheKey", () => new ExampleClass() { Message = "Nope - already cached" );

// prints 'Hello' from the first cached result
Console.WriteLine(cacheResult2.Message);
           
// changing the original cached object outside LazyCache
cacheResult1.Message = "Hola"; 
var cacheResult3 = cache.GetOrAdd("SomeLongCacheKey", () => new ExampleClass() { Message = "Still nope" );

// prints 'Hola'
Console.WriteLine(cacheResult3.Message);

Caching bools and other value types - the default(bool) is false

Caching simple value types like a bool can be missleading and is best avoided because the default for a value type may not be what you expect.

If you retrieve a bool from the cache with value false that could occur because you cached the false value. But it could also be because the default value for a bool is false and the value did not exist in the cache!

Always cache the nullable flavour of value types so you can check for null and be certain if you hit the cache or missed, and avoid confusion with the default value.