ASP.NET缓存,限制缓存

时间:2015-05-31 17:46:35

标签: c# asp.net caching

我试图在ASP.NET中为Web应用程序实现数据缓存,这是针对类的,我被要求限制ObjectCache中的条目数,而不是内存大小,而是通过条目本身的数量。这很简单,因为我可以调用ObjectCache.Count,但是当缓存超出既定限制(5,仅用于测试)时,我无法弄清楚如何删除存储的最旧元素,因为它按字母顺序排列排序

这是在数据访问层的服务中实现的,因此我无法使用任何其他结构(如队列)来跟踪缓存中的插入。

我该怎么办?有没有办法在缓存中过滤或获取旧元素?

这是方法代码

        public List<EventSummary> FindEvents(String keywords, long categoryId, int start, int count)
    {
        string queryKey = "FindEvent-" + start + ":" + count + "-" + keywords.Trim() + "-" + categoryId;
        ObjectCache cache = MemoryCache.Default;
        List<EventSummary> val = (List<EventSummary>)cache.Get(queryKey);
        if (val != null)
            return val;

        Category evnCategory = CategoryDao.Find(categoryId);
        List<Event> fullResult = EventDao.FindByEventCategoryAndKeyword(evnCategory, keywords, start, count);
        List<EventSummary> summaryResult = new List<EventSummary>();

        foreach (Event evento in fullResult)
        {
            summaryResult.Add(new EventSummary(evento.evnId, evento.evnName, evento.Category, evento.evnDate));
        }

        if (cache.Count() >= maxCacheSize)
        {
            //WHAT SHOULD I DO HERE?
        }

        cache.Add(queryKey, summaryResult, DateTime.Now.AddDays(cacheDays));

        return summaryResult;
    }

2 个答案:

答案 0 :(得分:0)

如评论中所述,Trim method from MemoryCache有一个LRU(最近最少使用)政策,这是您在此处寻找的行为。遗憾的是,该方法不是基于要从缓存中删除的绝对对象数,而是基于百分比,即int参数。这只是意味着,如果你试图破解它并以1 / cache.Count()作为百分比传递,你就无法控制真正从缓存中删除了多少对象,这不是一个理想的场景。

另一种方法是使用DIY方法,而不是使用.NET缓存实用程序,因为在我们的例子中,它们似乎并不完全符合您的需求。我正在考虑SortedDictionary的某些内容,其中缓存对象的时间代码作为键,并且在您给定值时,在给定时间码下插入缓存中的缓存对象列表。尝试重现您已经使用的.NET缓存行为并不是太大胆,并且自己直接控制删除策略的附加好处将是一个好的,IMO,并不是太大胆。

答案 1 :(得分:0)

作为旁注,与您的问题没有直接关系,
管理内存模型中缓存的最大问题是GC。 当您开始存储超过几百万个条目时,即使使用最先进的非阻塞GC,也会要求最终GC暂停。

很难缓存超过16 Gb,不会偶尔暂停5-6秒(即全部停止)。

我之前在此处描述过:https://stackoverflow.com/a/30584575/1932601 如果您需要存储非常多的过期条目(比如1亿条聊天消息),那么按原样缓存对象最终是一个糟糕的选择

看看我们做了多长时间存储数亿个对象而不杀死GC的做法。

https://www.youtube.com/watch?v=Dz_7hukyejQ