【问题标题】:Automatically re-populate the cache at expiry time到期时自动重新填充缓存
【发布时间】:2011-04-12 07:13:56
【问题描述】:

我目前缓存了一个方法调用的结果。

缓存代码遵循标准模式:如果缓存中的项目存在,它会使用它,否则它会计算结果,在返回之前将其缓存以供将来调用。

我想保护客户端代码免受缓存未命中(例如,当项目过期时)。

我正在考虑生成一个线程来等待缓存对象的生命周期,然后在现有项目到期时(或之前)运行提供的函数来重新填充缓存。

任何人都可以分享与此相关的任何经验吗?这听起来是不是一种明智的做法?

我正在使用 .NET 4.0。

【问题讨论】:

  • 我将在 asp.net 中使用缓存。我觉得这个方法相对独立于技术,所以我提出了相对技术不可知的问题。
  • 我正在研究这个并考虑使用 System.Timers.Timer 而不是生成一个新线程并且是在到期前刷新。

标签: c# .net caching


【解决方案1】:

由于这是 ASP.NET,Cache.Insert() 方法允许您指定回调委托。

这听起来是一种明智的做法吗?

是的,回调(和文件依赖)正是针对这种情况提供的。您仍然需要在资源、延迟和过时之间进行权衡。

【讨论】:

  • 这回答了我最初设想的问题。我不确定 Steven Sudit 在缓存和快照之间所做的区别是否有用(我以前没有遇到过这种区别)。我有兴趣了解更多。
  • 在回调中你失去了当前的 http 上下文,有没有一种优雅的方法来解决这个问题?
【解决方案2】:

.NET Framework 4.0 的新增功能是MemoryCache Class

引用自文档:

MemoryCache 类类似于 ASP.NET 缓存类。这 MemoryCache 类有很多属性 以及访问缓存的方法 你会很熟悉,如果你 已经使用了 ASP.NET Cache 类

如果不存在,您可以使用 AddOrGetExisting 方法获取或创建 CacheItem。

【讨论】:

  • 不错的链接,不知道。但是 AddOrGetExisting 仍然算作缓存未命中,Ben 应该使用回调。这似乎支持。
【解决方案3】:

这是一个永不过期的缓存:

var cache = new ConcurrentDictionary<TKey, TValue>();

var value = cache.GetOrAdd(someKey, key => MyMethod(key));

这有帮助吗?


这是一个永不过期的缓存,并在某个生命周期后刷新值:

var cache = new ConcurrentDictionary<TKey, Tuple<TValue, DateTime>>();

var value = cache.AddOrUpdate(someKey,
             key => Tuple.Create(MyMethod(key), DateTime.Now),
    (key, value) => (value.Item2 + lifetime < DateTime.Now)
                  ? Tuple.Create(MyMethod(key), DateTime.Now)
                  : value)
                  .Item1;

这有帮助吗?

【讨论】:

  • 但它也从不刷新任何东西
  • 好的,不错的补充。但是ASP缓存也有优先级机制abs timeout,sliding timeout,defaults,...(还是+1 :)
  • 我通常更愿意让一个旧值过期,然后推迟获取一个新值,直到它真正需要为止。
  • @Steven:这对 OP 的情况做出了太多假设。
  • @Henk:也许吧,但您所描述的不是缓存,而是快照。例如,如果我有一个很少更改的数据表,例如美国的州列表,我不想每次都访问数据库,但我也不想永远缓存列表,因为,嘿,事情变了。因此,我生成了一个在一段合理但任意的时间段(一小时、一天)后过期的快照,然后用新的快照替换它。那不是缓存。缓存将保留过期的值,以便为更有用的值腾出空间,并根据需要解决未命中的问题。
【解决方案4】:

让一个对象过期并立即重新创建它似乎没有任何意义。只需关闭过期; dtb 显示了如何。

【讨论】:

  • 刷新呢?这是缓存的另一个功能。
  • 旧物件比新物件差多少?如果不是,那我们就别管它了。另一方面,如果 OP 有一个简单的包装器,相当于“如果可能,从缓存中获取它,否则创建它并顺便将其添加到缓存中”,这很好。
  • 如果它是一个静态计算,你会是对的。但是考虑一个查询或网络服务。缓存通常是性能和新鲜度之间的权衡。 OP 解决了另一部分问题:防止缓存未命中
  • 您无法防止缓存未命中。这就是为什么它被称为缓存。
  • @Henk:对不起,又忘记了前缀。
猜你喜欢
  • 2013-01-27
  • 1970-01-01
  • 1970-01-01
  • 2017-06-16
  • 1970-01-01
  • 2019-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多