Search code examples
c#.netcachingmemorycacheobjectcache

Memory Cache not working in .Net Framework 4


My project is built on .Net Framework 4.0 and we are using built in ObjectCache as MemoryCache which is implemented in System.Runtime.Caching.

It was working fine previously but suddenly it has stopped saving anything on the cache. When I call Set method on cache it doesn't save anything and the Result View is always empty, stating Enumeration yielded no results. I double checked the code and found no catch there. It's really as simple as something like below:

var policy = new CacheItemPolicy();
cache = new MemoryCache("MyCache");
cache.Set("item", "item value", policy);
var item = cache.Get("item");
cache.Remove("item"); //when removal is required

However, a sample application targeting .Net Framework 4 on the same machine works. I was wondering if anyone else has experienced similar behavior and how could I get to the core of this issue? Is there any tool out there to help?


Solution

  • I finally found the cause of error. I was disposing container that had container controlled instance of Cache. When container was disposing, it was also disposing my cache. And it was unable to Set values on a disposed cache object. It should have thrown exception but it didn't, hence the whole confusion. Future readers please be aware.

    var CachingPolicy = new CacheItemPolicy();
    var Cache = new MemoryCache("YourCacheName");
    container.RegisterInstance(CachingPolicy);
    container.RegisterInstance(Cache);
    
    container.Dispose(); //disposes cache as well. But calling methods on cache object won't throw exception.
    
    //at this point, you should create the cache again, like
    CachingPolicy = new CacheItemPolicy();
    Cache = new MemoryCache("YourCacheName");
    container.RegisterInstance(CachingPolicy);
    container.RegisterInstance(Cache);
    

    Further digging in MemoryCache code through ILSpy cleared that, it doesn't set anything if the object is disposed.

    if (IsDisposed)
    {
        if (collection != null)
        {
            foreach (ChangeMonitor item in collection)
            {
                item?.Dispose();
            }
        }
    }
    else
    {
        MemoryCacheKey memoryCacheKey = new MemoryCacheKey(key);
        MemoryCacheStore store = GetStore(memoryCacheKey);
        store.Set(memoryCacheKey, new MemoryCacheEntry(key, value, absExp, slidingExp, priority, collection, removedCallback, this));
    }