0

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?

Saad
  • 198
  • 2
  • 12
  • If you change the name of the `MemoryCache` to something else, does it start working again? – Blue Oct 20 '18 at 17:31
  • What does your Result view refer to, where are you assigning it to the Get value fetched, no where in this code. Are you getting `item` as null. Also what's `CacheItemPolicy` – Mrinal Kamboj Oct 20 '18 at 17:39
  • 1
    @FrankerZ Cache instance is registered in Container and passed around. Strangely when I registered the cache with new name. The one resolved is still getting "Default" named cache. I need to check from where is it getting that cache. – Saad Oct 20 '18 at 17:43
  • @MrinalKamboj I'm referring to `Result View` that we can see while debugging. Its empty right after setting an item to cache. If I call `cache.GetCount()` i get 0. `CacheItemPolicy` is initialized to its default. – Saad Oct 20 '18 at 17:47
  • Even below three consecutive lines of code is not working in my project. `Cache = new MemoryCache("MyCache"); CachingPolicy = new CacheItemPolicy(); Cache.Set("item", "value", CachingPolicy);` It assigns "Default" name to cache and doesn't set the value. Probably an internal bug in assembly or framework. – Saad Oct 20 '18 at 18:04

1 Answers1

0

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));
}
Saad
  • 198
  • 2
  • 12
  • Which container is this ? Docker or Dependency Injection ? – Mrinal Kamboj Oct 21 '18 at 07:56
  • @MrinalKamboj its Unity DI container. – Saad Oct 21 '18 at 08:12
  • Then you have posted half information, anything that's disposed is anyway never a valid object, this has nothing to do with cache and why would you even dispose cache during initialization – Mrinal Kamboj Oct 21 '18 at 11:52
  • I wasn't sure that lifetime of my cache was as of container. I'd have thrown `ObjectDisposedException` on `Set` method of cache to at least inform caller that the object is disposed. Also, I'm disposing container to load services on user's token during log in. Hope its clear now. – Saad Oct 21 '18 at 14:24