ASP.NET持久缓存(“延迟加载”式?)

时间:2009-06-29 14:49:28

标签: c# asp.net caching

我在使缓存按照我想要的方式工作时遇到了一些麻烦。

问题: 检索所请求数据的过程非常耗时。如果使用标准的ASP.NET缓存,一些用户将会“检索”检索数据。这是不可接受的。

解决方案?: 数据100%当前并不是非常重要。我希望在更新另一个线程中的缓存数据时提供旧的无效数据,使新数据可用于将来的请求。我认为数据需要以某种方式持久化,以便能够在应用程序重新启动后为第一个用户提供服务,而不会让用户“点击”。

我已经提出了一个解决方案,它可以解决上述问题,但我想知道是否存在“最佳实践”方式,或者是否存在支持此行为的缓存框架?

6 个答案:

答案 0 :(得分:3)

有一些工具可以做到这一点,例如微软ISA服务器(可能有点贵/过度杀伤)。

您可以使用Enterprise Libary Caching将其缓存在内存中。让您的用户从缓存读取,并有其他页面更新缓存,这些其他页面应该定期调用,以保持数据最新。

答案 1 :(得分:1)

您可以在删除缓存项目时进行侦听,然后处理

public void RemovedCallback(String k, Object v, CacheItemRemovedReason r)
{
    // Put Item Back IN Cache, ( so others can use it until u have finished grabbing the new data)

    // Spawn Thread to Go Get Up To Date Data

    // Over right Old data with new return... 
} 

在全球的asax中

protected void Application_Start(object sender, EventArgs e)
{
     // Spawn worker thread to pre-load critical data
}

哦......我不知道这是不是最好的做法,我只是觉得它很光滑〜 祝你好运〜

答案 2 :(得分:1)

我在内存中使用Dictionary / Hashtable创建了自己的解决方案,作为实际缓存的副本。当一个方法调用从缓存中请求对象并且它不存在但存在于内存中时,返回了内存存储对象,并使用委托方法触发了一个新线程来更新内存和缓存中的对象。 / p>

答案 3 :(得分:1)

使用.NET内置的CacheTimer类,您可以非常轻松地完成此操作。 Timer在一个单独的线程上运行。

我实际上编写了一个名为WebCacheHelper的非常小的包装器库,它在重载的构造函数中公开了这个功能。该库还充当Cache对象周围的强类型包装器。

这是一个如何做到这一点的例子......

public readonly static WebCacheHelper.Cache<int> RegisteredUsersCount = 
  new WebCacheHelper.Cache<int>(new TimeSpan(0, 5, 0), () => GetRegisteredUsersCount()); 

这有一个延迟加载方面,GetRegisteredUsersCount()将在RegisteredUsersCount首次访​​问的那一刻在调用线程上执行。但是,之后它在后台线程上每5分钟执行一次。这意味着唯一将在等待时间较长的情况下受到惩罚的用户将是第一个用户。

然后获取值就像引用RegisteredUsersCount.Value一样简单。

答案 4 :(得分:0)

是的,您可以在应用启动时缓存最常访问的数据,但这仍然意味着第一个触发的用户会按照您的说法“接受命中”(当然假设是inproc缓存)。

答案 5 :(得分:0)

我在这种情况下所做的是在db中使用CacheTable来缓存最新数据,并运行后台作业(在共享环境中使用Windows服务,也可以使用线程)刷新表上的数据。

向用户显示空白屏幕的可能性很小。我通过asp.net缓存缓存1分钟来消除这种情况。

不知道这是不是一个糟糕的设计,但它在高度使用的网站上运行良好而没有问题。