使用HttpRuntime.Cache发布问题

我使用以下.net代码将对象添加到缓存:

public static void Add(string key, T dataToCache) { try { ApplicationLog.Instance.WriteInfoFormat("Inserting item with key {0} into Cache...", key); HttpRuntime.Cache.Insert( key, dataToCache, null, DateTime.Now.AddDays(7), System.Web.Caching.Cache.NoSlidingExpiration); } catch (Exception ex) { ApplicationLog.Instance.WriteException(ex); } } 

这是我从缓存中检索值的代码:

 public static T Get(string key) { try { if (Exists(key)) { ApplicationLog.Instance.WriteInfoFormat("Retrieving item with key {0} from Cache...", key); return (T)HttpRuntime.Cache[key]; } else { ApplicationLog.Instance.WriteInfoFormat("Item with key {0} does not exist in Cache.", key); return default(T); } } catch(Exception ex) { ApplicationLog.Instance.WriteException(ex); return default(T); } } public static bool Exists(string key) { bool retVal = false; try { retVal= HttpRuntime.Cache[key] != null; } catch (Exception ex) { ApplicationLog.Instance.WriteException(ex); } return retVal; } 

但我发现每隔2分钟左右,缓存的对象值将被设置为null,从而再次从数据库中提取该值。

我在这里缺少什么?

当你每隔两分钟说插入的值设置为null时,这是否意味着你感兴趣的项目或缓存中的每一项?

我问这个是因为只要应用程序正在运行,缓存就会存在。 如果重新启动应用程序,缓存就会消失。 这可以解释如果每2分钟一切都消失的行为。 在这种情况下,您手上有一个不同的问题:为什么应用程序每2分钟重新启动一次。

如果它只是一些项目,那么它可能是一个内存问题。 缓存会自行清理以响应内存不足。 我相信有一种方法可以为插入的值设置优先级。 但是当你内存不足时,这应该只是一个问题。

如果这仍然无法解决您的问题,则有一种方法可以发现删除项目的原因。 这里解释一下 。

首先,您的访问权限不同步,因此这是一个很好的问题来源。 从HttpRuntime Cache读取保证是线程安全的,因此您应该尝试读取您的项目作为每个缓存操作的第一步。

在检查是否Exists和实际检索项目之间可能发生很多事情(例如您的项目不再在那里)。 你应该得到你正在寻找的项目的句柄,如果不是,那么通过从持久数据存储中获取它来提供线程安全插入。

因此,您的Add逻辑将进入您的Get IF数据不在那里。 提供单独的Add逻辑并没有什么根本性的错误,与阻止对特定数据的进一步请求相比,您应该多次测量数据库的命中成本。

 T GetT(string key) { T item = (cache.Get(key) as T); if (item == null) { lock (yourSyncRoot) { // double check it here item = (cache.Get(key) as T); if (item != null) return item; item = GetMyItemFromMyPersistentStore(key); // db? if (item == null) return null; string[] dependencyKeys = {your, dependency, keys}; cache.Insert(key, item, new CacheDependency(null, dependencyKeys), absoluteExpiration, slidingExpiration, priority, null); } } return item; } 

根据您的到期策略,您可以将数据存储在内存中并提供对其的快速和同步访问,但正如我所说,测量它并根据您的需要进行调整。 在更新项目并将其正确保存到持久存储之后的业务逻辑中,只需将其从缓存中删除,然后下一次调用Get将再次获取它。

这可能是因为内存不足,当内存变得稀缺时,缓存将自动终止缓存中的项目。如果您希望在另一个项目之前清除一个项目,则有一个可选参数来设置缓存中项目的优先级。