Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 访问MemoryCache是否会创建副本?_C#_Linq_Memorycache - Fatal编程技术网

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()