Search code examples
c#linqmemorycache

Does accessing MemoryCache create a copy?


I have a cache service like this:

public interface ICacheService {
    T Get<T>(string cacheID, Func<T> getItemCallback, int cacheMinutes = 5) where T : class;
}

public class MemoryCacheService : ICacheService {
    public T Get<T>(string cacheId, Func<T> getItemCallback, int cacheMinutes = 5) where T : class {
        T item = MemoryCache.Default.Get(cacheId) as T;
        if (item == null) {
            item = getItemCallback();
            MemoryCache.Default.Add(cacheId, item,
                new CacheItemPolicy {AbsoluteExpiration = DateTime.Now.AddMinutes(cacheMinutes)});
        }
        return item;
    }
}

And retrieved like this:

var result = _cache.Get("mylist", () => _database.Fetch<MyList>().AsQueryable(), 600);

The list is large and accessed frequently in a per keystroke type-ahead dropdown. And the query condition is also dynamic, like

if (this) result = result.Where(x=> this ...)
if (that) result = result.Where(x=> that ...)
finally result.ToList() 

I wonder, every time I access the list from cache, does the system create a copy of the data before start building linq query? If so, it's like copy-per-keystroke, not very efficient. Or does the it deferred the query because I'm retrieving AsQueryable and build linq?

Any better alternatives? Thanks


Solution

  • No, MemoryCache does not make a copy. You basically store a reference to some object instance in the cache, and that is what you get back when you access an item in the cache.

    I don't have a formal documentation link, but found out the "hard way" in practice, where I accidentally modified the cached object by just using the reference I got back (without copying it).

    Also, studying the reference sources (http://referencesource.microsoft.com) shows that there is no automatic copying happening.

    Depending on your application and needs, you might to want sure that the types you cache are actually immutable by design.