-
Notifications
You must be signed in to change notification settings - Fork 159
Troubleshooting LazyCache
To get help with your issue it will assist if others can recreate your problem easily. The simplest way to to that is to create a tiny console app that reproduces the problem you are having. Use the dotnet CLI and the code below as a starting point, and then file an issue here (slow response time - usually just the author!) or on stack overflow (faster - lots more people!).
makedir minimal_repro
cd minimal_repro
dotnet new console
dotnet add package lazycache
And then in Program.cs
place the following:
using System;
using LazyCache;
namespace minimal_repro
{
class Program
{
static void Main(string[] args)
{
IAppCache cache = new CachingService();
var result = cache.GetOrAdd("key", () => {
Console.WriteLine("Hello from the cache!");
return new object();
});
Console.ReadLine(); }
}
}
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 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.