我已经构建了一个不错的小类,用作缓存。每个项目都有一个过期时间跨度或日期时间。每次尝试访问缓存中的项目时,都会检查该项目的过期时间,如果过期,则将该项目从缓存中删除并且不返回任何内容。
这对于经常访问的对象来说非常有用,但是如果一个项目被放入缓存中并且再也不会被访问,那么即使它已经过期,它也永远不会被删除。
从缓存中使此类项目过期的好方法是什么?
我是否应该有一个后台线程无限枚举缓存中的每个项目以检查它是否已过期?
The best code is no code. Use the ASP.NET cache instead. You can reference it as System.Web.HttpRuntime.Cache in any application, not just web applications.
您可以实施 LRU(最近最少使用)策略,保持您的项目按访问时间排序,当一个新项目插入缓存并且缓存已满时,您驱逐该列表中最后一个项目。请参阅Wikipedia 上的缓存算法。
如果您想立即过期,我仍然只会在访问内容时这样做。即当缓存对象被访问并且它的时间已经过期时重新获取它。
您还可以对缓存的任何更改(重新)启动一个 Timer,并将 Interval 设置为最接近的到期时间戳。这不会精确到毫秒,并且取决于消息泵的运行,但对资源的要求不是很高。
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 应用程序。如果它是一个网络应用程序,你已经内置了滑动到期。然后,您可以将其包装在强类型包装器中,以避免每次都按键引用缓存项。