none
Cache如何不影响过期而进行遍历? RRS feed

  • 问题

  • 如题,一个WEB项目中,使用 MemoryCache 类 (System.Runtime.Caching) 做数据库缓存。
    每从数据库构造一个Model,都会用其主键(Guid)作为Key添加到Cache中。


    然后当我要按照某个条件(非主键),想要查找一个Model时,我也会先去缓存里查找,如果找不到再去数据库取。
    例如 Cache.Select(x => (Model)x.Value).FirstOrDefault(y => y.Name == param);
    用这种方式遍历Cache,查找我需要的对象。

    但问题随之产生,因为Model数量庞大,并不是所有的Model都要频繁访问,因此我设置了15分钟的闲置过期时间(CacheItemPolicy.SlidingExpiration 属性)。


    而一旦对Cache进行遍历,可能就会刷新整个缓存的闲置时间,导致真正闲置的对象不能得到释放。

    补充:MSDN并没有表明具体什么样的操作叫做访问,后来通过实验证明,Select并不会影响对象的过期,似乎只有Get方法才会使对象“活跃”。


    那么剩下的问题就是,MSDN上有一句警告:Retrieving an enumerator for a MemoryCache instance is a resource-intensive and blocking operation. Therefore, the enumerator should not be used in production applications.
    进行Linq Select操作应该是需要转换IEnumrable的,因此我怀疑我这么设计是否正确。

    另一种方案是,根据条件去数据库中检索对象的ID,然后到Cache中按ID查找对象,找不到再去数据库构造完整对象。不知道哪个方案效率更高呢?


    (数据库中有大量外键,构造一个复杂的Model对象可能需要联合十多张表查询,因此我需要缓存!)


    • 已编辑 PM_NUAA 2015年9月3日 23:52 解决了一部分问题
    2015年9月3日 23:28

答案

  • 感谢 @韦恩卑鄙 指点,发现还是针对不同查询条件,建立多个不同Key的Cache比较好,占用的也只是多倍指针(引用)的空间,而查询效率却可以大幅提升了。
    • 已标记为答案 PM_NUAA 2015年9月4日 0:14
    2015年9月4日 0:14