我有一个很好的小类,可以充当缓存。每个项目都有一个到期TimeSpan或DateTime。每次尝试访问缓存中的项目时,都会检查项目的到期时间,如果项目已过期,则会从缓存中删除该项目,并且不会返回任何内容。

这对于经常访问的对象来说非常棒,但是如果某个项目放在缓存中并且从未再次访问过,那么它永远不会被删除,即使它已过期。

从缓存中过期这些项目的好方法是什么?

我是否应该让后台线程无限枚举缓存中的每个项目以检查它是否已过期?

有帮助吗?

解决方案

根据我的经验,维护自定义缓存机制变得比它值得更麻烦。有几个库已经解决了这些问题。我建议使用其中一个。 .Net中很受欢迎的是企业库,尽管我对其缓存能力的经验有限。

如果您必须使用自定义缓存机制,那么我认为您建议的注意线程概念没有问题。也就是说,如果您的应用程序是基于服务器的应用程序而不是Web应用程序。如果它是一个Web应用程序,您已经内置了滑动过期。然后,您可以将其包装在强类型包装器中,以避免每次都按键引用缓存项。

其他提示

最好的代码是没有代码。请改用ASP.NET缓存。您可以在任何应用程序中将其引用为System.Web.HttpRuntime.Cache,而不仅仅是Web应用程序。

您可以实施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);
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top