如何从缓存中清除过期的项目?
我有一个很好的小类,可以充当缓存。每个项目都有一个到期时间跨度或者日期时间。每次尝试访问缓存中的项目时,都会检查该项目的到期时间,如果该项目已过期,则将其从缓存中删除,并且不返回任何内容。
这对于经常访问的对象非常有用,但是,如果将一项放置在缓存中并且再也没有访问过,即使它已过期,也永远不会删除它。
有什么好的方法可以使此类项目从缓存中过期?
我是否应该有一个后台线程来无限枚举缓存中的每个项目,以检查其是否过期?
解决方案
我们可以实施LRU(最近最少使用)策略,按访问时间对项目进行排序,当新项目插入到缓存中并且缓存已满时,我们将逐出该列表中的最后一个项目。请参阅Wikipedia上的缓存算法。
如果我们想立即过期,我仍然只会在访问某些内容时才这样做。 IE。当访问缓存对象并且时间已到时,对其进行重新获取。
我们还可以对缓存进行任何更改(重新)以将Interval设置为最接近的到期时间戳记来启动Timer。这将不会精确到毫秒,并且取决于运行的消息泵,但是对资源的要求不是很高。
但是,如果我们不介意在不更新缓存时对象永远挂着,那么Harald Scheirich的答案会更好。
在最后一次清除项目后1分钟后,我们可以在第一次访问时从缓存中清除适当的旧项目。
private DateTime nextFlush; public object getItem(object key) { DateTime now = DateTime.Now if (now > nextFlush) { Flush(); nextFlush = now.AddMinutes(1) } return fetchItem(key); }
以我的经验,维护自定义缓存机制比它值得的麻烦更多。那里有几个库已经解决了这些问题。我建议使用其中之一。 .Net中流行的一个是企业库,尽管我对其缓存功能的经验有限。
如果必须使用自定义的缓存机制,那么我们建议的警惕线程想法将不会有问题。也就是说,如果应用程序是基于服务器的应用程序而不是Web应用程序。如果它是一个Web应用程序,则我们已经内置了滑动到期时间。然后,我们可以将其包装在强类型包装器中,以避免每次都通过键引用缓存项。
最好的代码是没有代码。请改用ASP.NET缓存。我们可以在任何应用程序中(不仅仅是Web应用程序)将其引用为System.Web.HttpRuntime.Cache。