我使用Http.Current.Cache存储从我的数据库中检索的各种值,因为我的应用程序是数据密集型的。在我的新笔记本电脑上使用VS2017安装运行我的网站时(在VS2015的另一台笔记本电脑上,我从未见过这个问题),我看到一个非常奇怪的问题,其中缓存的值似乎被随机清除 - 几乎是以违反逻辑的方式。
例如,我有一个 if 子句,其条件是所讨论的缓存项不为null。我的代码肯定是通过这个 if 语句的路径,但稍后调试器显示缓存项实际上是空的 - 导致我的应用程序失败。
public static SportSeason GetCurrentSportSeason(string sportCode)
{
SportSeason sportSeason = null;
string key = "Sheets_SportSeason_" + sportCode;
int i = 0;
if (BaseSheet.Settings.EnableCaching && BizObject.Cache[key] != null)
{
i = 1;
sportSeason = (SportSeason)BizObject.Cache[key];
}
else
{
i = 2;
sportSeason = GetSportSeasonFromSportSeasonDetails(SiteProvider.Sheets.GetCurrentSportSeason(sportCode));
BaseSheet.CacheData(key, sportSeason);
}
if(sportSeason == null)
{
int j = i;
}
return sportSeason;
}
我可以在final if中设置断点,并且变量i设置为1,但sportSeason对象为NULL(缓存条目也是如此)。如果缓存项不为空,代码进入第一个 if 子句的唯一方法是什么呢?
中带有断点的监视变量这很难追查,因为它在我的业务对象中随机发生。有时候,在看到这个问题之前,我必须刷新页面3到4次。
如何快速地使缓存失效,以及通过什么?屏幕截图显示缓存项目不多,所以我不认为我的内存不足。并且没有其他进程正在运行,这可能会破坏缓存。
编辑:通过更多调试,我确定只有在断点处再次检查时,才会清除第91行上检查的缓存键(设置为空)。所有其他缓存记录仍然存在。
EDIT2:我已将问题归结为此问题,尽管它仍然似乎无视逻辑:
HttpContext.Current.Cache.Insert("ABC", "123", null, DateTime.Now.AddSeconds(600), TimeSpan.Zero);
int i = 0;
我清除了所有缓存。当我跳过Cache.Insert语句时,我的缓存计数变为1.但是,根据该键的缓存项目保持为空(请参阅监视窗口)。
另外,如果我再执行一个语句(int i = 0),缓存计数会回到零。
Edit3:这是杀死我的Insert()的AbsoluteExpiration参数。时钟已关闭。
如果我将AbsoluteExpiration设置为未来5小时(300分钟),则无效。如果我将它设置为将来的5小时1分钟(301分钟),一切正常。
HttpContext.Current.Cache.Insert("ABC", "123", null, DateTime.Now.AddMinutes(301), TimeSpan.Zero);
我的笔记本电脑上的时钟是100%准确的,您可以看到Intellisense也显示正确的时间。缓存是否可以基于5小时的其他时钟?
Edit4:看起来像someone else is off by 5 hours。
答案 0 :(得分:7)
修复是在指定AbsoluteExporation参数时始终使用DateTime。 Utc 现在而不是DateTime.Now。
这样做:
react-native-cli
不是这个:
HttpContext.Current.Cache.Insert("ABC", "123", null, DateTime.UtcNow.AddMinutes(1), System.Web.Caching.Cache.NoSlidingExpiration);
当我这样做时,它正确识别缓存是有效的,我可以检索该值。至于为什么在我的Windows 10 Pro笔记本电脑上需要这个,而不是在我的Windows 10 Home上,我不知道。
答案 1 :(得分:2)
您可以添加一个回调函数,该函数可以告诉您项目被删除的原因:
https://msdn.microsoft.com/en-us/library/7kxdx246.aspx
您在添加项目时指定回调,并在删除项目时触发。在其中放置断点或记录输出以打印出CacheItemRemovedReason
参数。
如果这对您没有帮助,您可以尝试在ASP.NET HttpContext Cache removes right after insertion的最佳答案中列出的调试步骤。如果应用程序正在终止,这可能会被捕获。
答案 2 :(得分:0)
检查IIS应用程序池回收选项以排除回收事件。因为application pool recycle, will clear your cache。
Per the App pool recycling settings docs:
您可以指定IIS以设置的时间间隔回收应用程序池 (例如每180分钟),在每天的特定时间或之后 应用程序池收到一定数量的请求。你也可以 配置元素以在何时重新启动应用程序池 工作进程虚拟内存和物理内存使用量达到了 具体门槛。
即使更改配置也可以回收应用池。
确保没有其他应用共享您的应用池,然后启用回收日志并重现问题。查看缓存消失是否与日志中的应用程序池回收相关联。如果是这样,请从那里确定回收发生的原因,然后进行配置更改,以便app pool在正常工作时间内不会回收。