System.Runtime.Caching strange behavior ?


  • Here's the output of my immediate window :

        (EmployeeCache as MemoryCache).Add("test", new Object(),DateTimeOffset.Now.AddMinutes(10));
        (EmployeeCache as  MemoryCache).GetCount()
        (EmployeeCache as  MemoryCache)
        [<namespace>.CustomCache]: {[<namespace>.CustomCache}
        base {System.Runtime.Caching.ObjectCache}: {<namespace>.CustomCache}
        CacheMemoryLimit: 1887436800
        DefaultCacheCapabilities: InMemoryProvider | CacheEntryChangeMonitors | AbsoluteExpirations |   SlidingExpirations | CacheEntryUpdateCallback | CacheEntryRemovedCallback
        Name: "keyname"
        PhysicalMemoryLimit: 99
        PollingInterval: {00:02:00}
    Under what conditions will adding to a MemoryCache return true, but an object will not be cached?

    Wednesday, July 20, 2011 1:30 PM


All replies

  • It shouldn't.  It calls AddOrGetExisting internally.  AddOrGetExisting returns null if the object doesn't exist -- which it shouldn't, and the conditional in Add returns true if the result is null.  What might be an issue is the call to GetCount.

    GetCount checks to see if the MemoryCache has been disposed, but it doesn't throw an ObjectDisposedException (that's a bug in my opinion).  Instead it simply returns 0.  Is your MemoryCache being disposed of before calling GetCount?

    Wednesday, July 20, 2011 4:10 PM
  • >>Is your MemoryCache being disposed of before calling GetCount ?

    I suspect the same. Don't have access to the box where I encountered this right now, but am going to test it by adding using a CacheItemPolicy with a RemovedCallback to see if the cached object is is being removed.

    Will get back to you after I do, but that still leaves open the question : What could cause a cached item to be evicted immediatley after caching it ? (the call to GetCount was done immediately after Add, the box has ample memory)




    Wednesday, July 20, 2011 7:43 PM
  • That's interesting.  Null is returned by AddOrGetExisting if the MemoryCache is disposed -- again no exception is thrown.  And since Add returns true if AddOrGetExisting returns null... well I think you have an answer.  Everything points to the MemoryCache object being in a disposed state.

    MemoryCache myCache = new MemoryCache("test");
    Console.WriteLine("Add result: " + myCache.Add("item1", new object(), null));
    Console.WriteLine("GetCount result: " + myCache.GetCount());

    Results shown in Console:
    Add result: True
    GetCount result: 0
    Press any key to continue . . .

    In my opinion, both Add and GetCount should throw exceptions when the MemoryCache object is disposed.

    Wednesday, July 20, 2011 8:34 PM
  • I added a bug report on Microsoft Connect for this.  See here:

    You can go to the page and indicate that you have the problem too.

    Wednesday, July 20, 2011 8:43 PM
  • So, I added a RemovedCallback expecting it be called if the object cached to EmployeeCache was being evicted immediatley after the Add. The callback isin't called, implying that the object was not added, which makes me think that your assumption is correct : the EmployeeCache was disposed already.

    I don't know how to test if the EmployeeCache is already disposed (no way to check this)

    I'm not sure of why my cache is being disposed. A static Dicitionary<string,CustomCache>(my cache repository, to which I only add entries) holds a reference to this cache, so AFAIK the Dispose should only be called when this dictionary itself is being disposed.

    I've +1'ed on the bug

    Thursday, July 21, 2011 10:16 AM
  • I cannot see how it could be in a disposed state unless something in your code is doing it.  Collections aren't disposable, so that's not going to be the source, but perhaps something in your inheriting (or wrappign) class CustomCache or in something that is using it...

    By the way, don't forget to mark my response as an answer if it's answered your question.

    Thursday, July 21, 2011 1:01 PM
  • I have the same problem, and I saw some people having it too.

    After the polling interval, MemoryCache get in disposed state and doesn´t store anything. I think it´s related to AppDomainUnload, that MemoryCache attach a event to it and call Dispose itself. - MCPD em .NET 2.0 MCTS em .NET 4

    Monday, September 03, 2012 11:52 AM