简体   繁体   English

访问MemoryCache是​​否创建副本?

[英]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? 我想,每次从缓存中访问列表时,系统是否会在开始构建linq查询之前创建数据的副本? 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? 或者它是否推迟了查询,因为我正在检索AsQueryable并构建linq?

Any better alternatives? 有更好的选择吗? Thanks 谢谢

No, MemoryCache does not make a copy. 不,MemoryCache不会复制。 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. 此外,研究参考源( http://referencesource.microsoft.com )表明没有自动复制发生。

Depending on your application and needs, you might to want sure that the types you cache are actually immutable by design. 根据您的应用程序和需求,您可能希望确保缓存的类型实际上是设计不可变的。

Without getting lost in the minutia of MemoryCache, you can reason this out with basic .NET design principles. 不要迷失在MemoryCache的细节中,你可以用基本的.NET设计原则来解决这个问题。 Only value types are easy to copy. 只有值类型易于复制。 There is no general mechanism to copy reference types, beyond [Serializable] and the very broken ICloneable. 除了[Serializable]和非常破碎的ICloneable之外,没有复制引用类型的通用机制。 Which are not requirements for an object to be put in the MemoryCache. 对于要放入MemoryCache的对象,这不是必需的。 So no. 所以不行。

Caching objects is very, very simple. 缓存对象非常非常简单。 A simple List<> gets that job done. 一个简单的List <>可以完成这项工作。 The value-add you get from MemoryCache is the other essential feature of an effective cache. 从MemoryCache获得的增值是有效缓存的另一个基本功能。 A retirement policy. 退休政策。 A cache without a policy is a memory leak. 没有策略的缓存是内存泄漏。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM