我有一个C#网页,我在其中存储了一个List<>服务器缓存中的对象,使用HttpContext.Current.Cache。第一页加载后,对象将保存在缓存中。当我刷新页面时,缓存对象为空。有什么想法吗?
另外,我想设置一个“工作”来每30分钟重新创建一个对象。我想在创建新版本之前提供缓存版本,然后用新版本替换旧版本。 我该怎么做?
在我的Global.asax中,在Application_Start中,我有以下内容:
HttpRuntime.Cache.Insert("MainADList", Uf.GetUsers(), null, Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(30));
当我需要它时,我会执行以下操作:
MainADList = (Users)HttpRuntime.Cache["MainADList"];
大部分是null。不总是,但几乎总是。
答案 0 :(得分:4)
即使使用Cache.NoAbsoluteExpiration
+ Cache.NoSlidingExpiration
填充缓存,ASP.NET也可以从缓存中删除项目(即:当可用系统内存不足时)。
将CacheItemPriority.NotRemovable
传递给Cache.Insert()以防止发生这种情况。 Lookup CachéItemPriority on MSDN.
长时间空闲,web.config /二进制更改等重新启动IIS应用程序池也会擦除缓存。查看this other SO post, HttpRuntime.Cache.Insert() Not holding cached value
关于创建作业以刷新缓存;我认为最好的Cache策略没有经验法则。它将在很大程度上取决于您的用户如何与您的网页进行交互,多长时间,多少并发,特别是在没有达到缓存时生成数据需要多长时间。
如果生成数据所花费的时间对于任何用户都是不可接受的,则可以设置刷新缓存的作业,但其间隔应小于缓存TTL +生成/检索所需时间的总和。 例如,如果您的缓存为30米并且生成数据需要2米,则刷新间隔必须为28米或更短,以避免任何用户点击空缓存。
答案 1 :(得分:2)
您可以使用System.Runtime.Caching
吗?这样你就不依赖于HttpRuntime命名空间了。
我怀疑你是因为网络服务器重启而.Net正在清除它。
的做法是否更好? public List<User> GetUsers()
{
var cache = System.Runtime.Caching.MemoryCache.Default;
if (cache["MainADList"] == null)
{
// Rebuild cache. Perhaps for Multithreading, you can do object locking
var cachePolicy = new System.Runtime.Caching.CacheItemPolicy() { AbsoluteExpiration = DateTime.Now + TimeSpan.FromMinutes(30) };
var users = Uf.GetUsers();
cache.Add(new System.Runtime.Caching.CacheItem("MainADList", users), cachePolicy);
return users;
}
return cache["MainADList"] as List<User>;
}