3

我有一个存储在 asp.net 缓存中的产品列表,但我在刷新缓存时遇到了问题。根据我们的要求,我想每 15 分钟刷新一次缓存,但我想知道,如果在刷新缓存的同时,如果某些用户要求提供产品列表,那么他应该得到错误还是旧列表或者他有等到缓存刷新。

示例代码如下

public class Product
{
    public int Id{get;set;}
    public string Name{get;set;}
}

我们有一个函数,它为我们提供 BLL 中的产品列表

public List<Product> Products()
{
       //////some code
}

Cache.Insert("Products", Products(), null, DateTime.Now.AddMinutes(15), TimeSpan.Zero);

我想在这里再添加一种情况,假设我使用静态对象而不是缓存对象,那么如果我们在独立服务器而不是集群上会发生什么以及哪种方法最好

4

1 回答 1

3

抱歉 - 这可能是幼稚/显而易见的,但只有一个外观类型类

if(Cache["Products"] == null)
{
        Cache.Insert("Products", Products(), null, DateTime.Now.AddMinutes(15), TimeSpan.Zero);
 }
 return Cache["Products"];

还有一个CacheItemRemoveCallback委托,您可以使用它来重新填充过期的缓存。作为备选

使用缓存对象而不是静态对象。显然更高效(Asp.net - 用于存储字典的缓存与静态变量)并且您可以获得所有缓存管理方法(滑动到期等)

编辑

如果担心更新时间,请考虑两个缓存对象加上一个控制器,例如

  1. 活动缓存
  2. 备份缓存 - 这是将要更新的缓存
  3. 缓存控制器(另一个缓存对象?)这将指示哪个对象处于活动状态

所以更新的过程将是

  1. 更新备份缓存
  2. 完成。支票有效
  3. 备份变为活动状态,反之亦然。该控件现在将备份缓存标记为处于活动状态

需要有一种方法在填充产品缓存对象时触发。我可能会使用CacheItemRemoveCallback委托来启动缓存重新填充。或者在外观类型类中进行异步调用 - 你不希望它阻塞当前线程

我敢肯定还有很多其他的变种

编辑 2

实际上考虑到这一点,我会让控制器类像这样

public class CacheController
{
    public StateEnum Cache1State {get;set;}
    public StateEnum Cache1State {get;set;}
    public bool IsUpdating {get;set;}
}

状态将是活动的、备份的、更新的,也可能是非活动的和错误的。您将IsUpdating在更新发生时设置标志,然后在完成后返回 false 以停止多个线程尝试一次更新 - 即竞争条件。该类只是一般原则,可以/应该根据需要进行修改

于 2013-06-24T11:22:27.600 回答