C# 访问MemoryCache是否会创建副本?
我有这样的缓存服务:C# 访问MemoryCache是否会创建副本?,c#,linq,memorycache,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&l
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;
}
}
var result = _cache.Get("mylist", () => _database.Fetch<MyList>().AsQueryable(), 600);
我想知道,每次我从缓存访问列表时,系统是否会在开始构建linq查询之前创建数据的副本?如果是这样的话,就像每次击键都复制一样,效率不高。还是因为我正在检索AsQueryable并构建linq,所以它推迟了查询
还有更好的选择吗?谢谢你,不要迷失在记忆缓存的细节中,你可以用基本的.NET设计原则来解释这一点。只有值类型易于复制。除了[Serializable]和非常脆弱的IClonable之外,没有复制引用类型的通用机制。这不是将对象放入MemoryCache的要求。所以没有
缓存对象非常非常简单。一个简单的列表可以完成这项工作。从MemoryCache获得的附加值是有效缓存的另一个基本特性。退休政策。没有策略的缓存是内存泄漏。否,MemoryCache不会复制。基本上,您将对某个对象实例的引用存储在缓存中,这就是您在访问缓存中的项时得到的结果 我没有一个正式的文档链接,但在实践中发现了“困难的方法”,我只是使用我得到的引用(没有复制它)意外地修改了缓存对象 此外,研究参考源()表明没有发生自动复制
根据您的应用程序和需要,您可能希望确保缓存的类型实际上在设计上是不可变的。您的意思是缓存、获取和查询都引用同一份数据?这似乎是有道理的。还有我在缓存服务中的CacheItemPolicy,这就是你提到的退休政策,对吗?我尝试了以下方法来测试你所说的<代码>列表1=_cache.Get(…);list1=list1.Take(2.ToList();list2=_cache.Get(…)代码>如果列表引用同一个对象,该列表不应该被截断为2吗?但似乎每次我都有完整的列表。没有,因为您正在创建一个新的列表实例。尝试对从缓存中获取的引用调用
Remove
。执行了一些测试。看起来任何返回列表的操作都会创建一个副本,然后更改list1引用。不确定每次改进后IQueryable都发生了什么,但由于直到最后的ToList才实现,我想我很好。谢谢所有的细节。
if (this) result = result.Where(x=> this ...)
if (that) result = result.Where(x=> that ...)
finally result.ToList()