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

Who*_*ver 9 c# linq memorycache

我有这样的缓存服务:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

并检索如下:

var result = _cache.Get("mylist", () => _database.Fetch<MyList>().AsQueryable(), 600);
Run Code Online (Sandbox Code Playgroud)

该列表很大,并且在每个击键类型提前下拉列表中经常访问.查询条件也是动态的,比如

if (this) result = result.Where(x=> this ...)
if (that) result = result.Where(x=> that ...)
finally result.ToList() 
Run Code Online (Sandbox Code Playgroud)

我想,每次从缓存中访问列表时,系统是否会在开始构建linq查询之前创建数据的副本?如果是这样,就像复制每按键一样,效率不高.或者它是否推迟了查询,因为我正在检索AsQueryable并构建linq?

有更好的选择吗?谢谢

Chr*_*n.K 15

不,MemoryCache不会复制.您基本上存储了对缓存中某个对象实例的引用,这是您在访问缓存中的项目时获得的内容.

我没有正式的文档链接,但在实践中找到了"困难的方法",我只是使用我回来的引用(不复制它)意外地修改了缓存的对象.

此外,研究参考源(http://referencesource.microsoft.com)表明没有自动复制发生.

根据您的应用程序和需求,您可能希望确保缓存的类型实际上是设计不可变的.


Han*_*ant 6

不要迷失在MemoryCache的细节中,你可以用基本的.NET设计原则来解决这个问题.只有值类型易于复制.除了[Serializable]和非常破碎的ICloneable之外,没有复制引用类型的通用机制.对于要放入MemoryCache的对象,这不是必需的.所以不行.

缓存对象非常非常简单.一个简单的List <>可以完成这项工作.从MemoryCache获得的增值是有效缓存的另一个基本功能.退休政策.没有策略的缓存是内存泄漏.