简体   繁体   English

在ASP.NET中使用缓存

[英]Using cache in ASP.NET

I'm trying to use the cache in an ASP.NET MVC web application to store some list data that rarely updates. 我正在尝试使用ASP.NET MVC Web应用程序中的缓存来存储一些很少更新的列表数据。 I insert this data into the cache in an UpdateCache() method like this: 我将这种数据插入UpdateCache()方法的缓存中,如下所示:

HttpContext.Current.Cache.Insert("MyApp-Products", products, null, DateTime.Now.AddYears(99), Cache.NoSlidingExpiration);

Then in my model I retrieve it: 然后在我的模型中检索它:

public static List<string> GetProducts()
{
    var cachedProducts = HttpContext.Current.Cache["MyApp-Products"];
    if (cachedProducts == null)
    {
        UpdateCache();
        cachedProducts = HttpContext.Current.Cache["MyApp-Products"];
    }
    return ((List<string>)cachedProducts );
}

The first time I visit the page, UpdateCache() is called as expected. 第一次访问该页面时,按预期方式调用UpdateCache() If I refresh, the data comes from the cache and I do not need to call UpdateCache() . 如果刷新,则数据来自缓存,而无需调用UpdateCache() However, after maybe 15 mins, I come back to the app and the cached values are gone. 但是,大约15分钟后,我回到了应用程序,缓存的值消失了。 My understanding was that this cache was per application, not session, so I would have expected it to still be there for myself or another user. 我的理解是,此缓存是针对每个应用程序而不是会话的,因此我希望它对于我自己或其他用户仍然存在。

Is there something wrong with the way I'm storing the cache? 我存储缓存的方式有问题吗? Or is there something I'm not understanding about how the Cache in ASP.NET works in a web app? 还是我对ASP.NET中的Cache在Web应用程序中的工作方式不了解?

My understanding was that this cache was per application, not session, so I would have expected it to still be there for myself or another user. 我的理解是,此缓存是针对每个应用程序而不是会话的,因此我希望它对于我自己或其他用户仍然存在。

While the cache is per application, ASP.NET doesn't provide you any guarantees that if you stored something into the cache you will find it back there. 虽然按应用程序缓存,但是ASP.NET不能为您提供任何保证,即使您将某些内容存储到缓存中也可以在其中找到它。 The cache could be evicted under different circumstances such as for example your server starts running low on memory and so on. 缓存可能在不同的情况下被驱逐,例如您的服务器开始运行的内存不足等。 You can subscribe to an event and get notified when an item is evicted from the cache. 您可以订阅事件并在从缓存中逐出项目时得到通知。 You can also define a priority when caching an item. 您还可以在缓存项目时定义优先级。 The higher the priority, the lower the chance of this item getting evicted. 优先级越高,将该项目逐出的机会越小。

Also since the cache is stored in the memory of the web server (by default) you should not forget the fact that your application domain could be recycled at any point by IIS. 另外,由于缓存存储在Web服务器的内存中(默认情况下),因此您不应忘记IIS随时可以回收您的应用程序域这一事实。 For example after a certain amount of inactivity or if it starts running low on memory or even if a certain CPU threshold usageis reached, ... and everything that is stored in the memory including the cache will simply disappear into the void and the next request in your application will start a new AppDomain. 例如,在一定数量的不活动之后,或者如果它开始在内存不足的情况下运行,或者即使达到一定的CPU阈值使用量,...,存储在内存中的所有内容(包括缓存)都将简单地消失为空,并且下一个请求在您的应用程序中将启动一个新的AppDomain。

But in any cases make sure that you check if the item is present in the cache before using it. 但是在任何情况下,请确保在使用之前检查缓存中是否存在该项目。 Never rely on the fact that if you stored something into it, you will find it. 永远不要依赖于以下事实:如果您将某些内容存储在其中,就会找到它。

All this blabla to come to the really essential point which is something very worrying with your code. 所有这些责骂到了真正重要的地步,这是您的代码非常令人担忧的事情。 It looks like you are storing a List<string> instance into the cache. 看起来您正在将List<string>实例存储到缓存中。 But since the cache is per application, this single instance of List<string> could be shared between multiple users of the application and of course this could happen concurrently. 但是由于缓存是针对每个应用程序的,因此List<string>单个实例可以在应用程序的多个用户之间共享,当然这可以同时发生。 And as you know List<T> is not a thread safe structure. 并且您知道List<T>不是线程安全的结构。 So with this code you will, at best, get an exception and at worst you will get corrupt data. 因此,使用此代码,您充其量只能得到一个异常,而最糟糕的是,您将得到损坏的数据。 So be very careful what you are caching and how you are synchronizing the access to the structure especially if you are caching a non thread-safe class. 因此,请特别小心要缓存的内容以及如何同步对结构的访问,尤其是在缓存非线程安全类的情况下。

IF this is on a full IIS, and happens around every 15minuntes. 如果这是在完整的IIS上进行的,则大约每15分钟发生一次。 Remember to check the Idle timeout value. 请记住检查空闲超时值。

That being said, if this list "never" changes, why not store it in a static array instead. 话虽如此,如果此列表“从不”更改,为什么不将其存储在静态数组中。

I can see how storing data in general in database is better than in static object. 我可以看到通常在数据库中存储数据比在静态对象中存储数据更好。 For one, in case data does change, it is easier to update DB than the application. 首先,万一数据确实发生变化,更新数据库比应用程序容易。

Try explicitly setting absolute expiration when caching your object: 尝试在缓存对象时显式设置绝对到期时间:

HttpRuntime.Cache.Insert("MyApp-Products", cachedProducts, null, DateTime.Now.AddDays(20), TimeSpan.Zero );

Note HttpRuntime is used instead of HttpContext for performance reasons even though the difference is minor. 注意出于性能原因,使用HttpRuntime代替HttpContext ,即使两者之间的差异很小。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM