Dbl
Dbl

Reputation: 5894

Memorycache won't store my object

So I've written a couple of wrapper methods around the System.Runtime MemoryCache, to get a general/user bound cache context per viewmodel in my ASP.NET MVC application.

At some point i noticed that my delegate just keeps getting called every time rather than retrieving my stored object for no apparent reason.

Oddly enough none of my unit tests (which use simple data to check it) failed or showed a pattern explaining that.

Here's one of the wrapper methods:

    public T GetCustom<T>(CacheItemPolicy cacheSettings, Func<T> createCallback, params object[] parameters)
    {
        if (parameters.Length == 0)
            throw new ArgumentException("GetCustom can't be called without any parameters.");

        lock (_threadLock)
        {
            var mergedToken = GetCacheSignature(parameters);
            var cache = GetMemoryCache();
            if (cache.Contains(mergedToken))
            {
                var cacheResult = cache.Get(mergedToken);
                if (cacheResult is T)
                    return (T)cacheResult;

                throw new ArgumentException(string.Format("A caching signature was passed, which duplicates another signature of different return type. ({0})", mergedToken));
            }

            var result = createCallback(); <!-- keeps landing here
            if (!EqualityComparer<T>.Default.Equals(result, default(T)))
            {
                cache.Add(mergedToken, result, cacheSettings);
            }

            return result;
        }
    }

I was wondering if anyone here knows about conditions which render an object invalid for storage within the MemoryCache.

Until then i'll just strip my complex classes' properties until storage works.

Experiences would be interesting nevertheless.

Upvotes: 0

Views: 2473

Answers (1)

Alexei Levenkov
Alexei Levenkov

Reputation: 100527

There are couple frequent reasons why it may be happening (assuming correct logic to actually add objects to cache/find correct cache instance):

  • x86 (32bit) process have "very small" amount of memory to deal with - it is relatively easy to consume too much memory outside the cache (or particular instance of the cache) and as result items will be immediately evicted from the cache.
  • ASP.Net app domain recycles due to variety of reasons will clear out cache too.

Notes

  • generally you'd store "per user cached information" in session state so it managed appropriately and can be persisted via SQL/other out-of-process state options.
  • relying on caching per-user objects may not improve performance if you need to support larger number of users. You need to carefully measure impact on the load level you expect to have.

Upvotes: 2

Related Questions