[ASP.NET] 如果将缓存“滑动过期时间”设置为1秒会怎样?

简介:

今天编写了一个采用ASP.NET Caching的组件,在为它编写Unit Test的过程中发现了一个有趣的问题,接下来我通过一个简单的实例说明这个问题。我们在一个控制台应用中编写了如下一段程序,这个段程序很简单:我们通过HttpRuntime的静态属性Cache得到表示当前缓存的Cache对象,并调用其Insert方法对当前的时间实施缓存。需要注意的是,我们采用“滑动时间”过期策略,并将这个滑动时间设置为1秒。

   1: class Program
   2: {
   3:     static void Main(string[] args)
   4:     {
   5:         string key = Guid.NewGuid().ToString();
   6:         HttpRuntime.Cache.Insert(key, DateTime.Now, null, Cache.NoAbsoluteExpiration, new TimeSpan(0, 0, 1) );
   7:         for (int i = 0; i < 5; i++)
   8:         {
   9:             Console.WriteLine(HttpRuntime.Cache.Get(key)??"N/A");
  10:             Thread.Sleep(500);
  11:         }
  12:     }
  13: }

接下来我们在一个for循环中提取缓存的时间并将其显示在控制台上,每次迭代之后会有0.5秒的休眠时间。根据缓存针对滑动时间过期策略,由于我们每隔0.5秒会读取缓存,所以在这段时间内缓存是不会过期的。但是如下所示的执行结果告诉我们,添加的缓存在1秒之后过期了。

   1: 4/1/2014 2:51:12 PM
   2: 4/1/2014 2:51:12 PM
   3: N/A
   4: N/A
   5: N/A

是否是ASP.NET缓存机制错了什么问题呢?其实不是,真正的原因是我们将滑动过期时间范围设置得太小了。为了证实这一点,我们按照如下的方式将这个时间设置为2秒。

   1: class Program
   2: {
   3:     static void Main(string[] args)
   4:     {
   5:         string key = Guid.NewGuid().ToString();
   6:         HttpRuntime.Cache.Insert(key, DateTime.Now, null, Cache.NoAbsoluteExpiration, new TimeSpan(0, 0, 2) );
   7:         for (int i = 0; i < 5; i++)
   8:         {
   9:             Console.WriteLine(HttpRuntime.Cache.Get(key)??"N/A");
  10:             Thread.Sleep();
  11:         }
  12:     }
  13: }

再次运行我们的程序后会的如下所示的输出结果,我们可以看到添加的缓存并没有过期。

   1: 4/1/2014 2:59:15 PM
   2: 4/1/2014 2:59:15 PM
   3: 4/1/2014 2:59:15 PM
   4: 4/1/2014 2:59:15 PM
   5: 4/1/2014 2:59:15 PM

通过查看相关源代码,我们发现这个问题的根源所在:如果我们调用Cache的Insert或者Add方法时指定了其slidingExpiration参数,针对该缓存项的每次提取操作,系统都会修改缓存项的过期时间(当前时间+slidingExpiration)。但是过期时间的修改是由前提的:它要求这个slidingExpiration参数指定的时间必须大于设定的最小时间,这个时间对应着内部类型CacheExpires具有如下定义的静态只读属性TimeSpan MIN_UPDATE_DELTA ,我们可以看到它的时间跨度正是1秒。所以如果我们指定的slidingExpiration参数小于1秒,实际上起不到“滑动过期 ”的作用。当然,在真实的项目中我们并不会将滑动时间设置的如此之短。

   1: internal sealed class CacheExpires
   2: {
   3:     //其他成员
   4:     internal static readonly TimeSpan MIN_UPDATE_DELTA = new TimeSpan(0, 0, 1);
   5: }

作者:蒋金楠
微信公众账号:大内老A
微博: www.weibo.com/artech
如果你想及时得到个人撰写文章以及著作的消息推送,或者想看看个人推荐的技术资料,可以扫描左边二维码(或者长按识别二维码)关注个人公众号(原来公众帐号 蒋金楠的自媒体将会停用)。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
相关文章
|
5月前
|
Web App开发 缓存 搜索推荐
HTML中meta标签中属性详解并设置页面缓存策略
HTML中meta标签中属性详解并设置页面缓存策略
298 0
|
7月前
|
缓存 NoSQL Java
Java实现redis缓存效果变量过期
Java实现redis缓存效果变量过期
73 0
|
1月前
|
存储 缓存 运维
LAMP架构调优(五)——网页缓存设置
LAMP架构调优(五)——网页缓存设置
10 1
|
6月前
|
缓存 开发框架 .NET
ASP.NET Core 缓存
Get新知识: 缓存相关概念:缓存的类型:总结:总的来说,私有缓存会减少网络带宽的需求,同时会减少从缓存到API的请求。因为私有缓存是存储在客户端浏览器的,对于请求来说,如果缓存还在有限期内,那么请求连网络请求都不会发出会直接在客户端浏览器获取到响应,这样就减少网络请求次数,同样也会减少API请求次数。而共享缓存不会节省缓存到API的网路带宽,但是它会减少请求到API的请求。因为共享缓存是...
32 0
ASP.NET Core 缓存
|
4月前
|
JSON 开发框架 .NET
ASP.NET Core Web API设置响应输出的Json数据格式的两种方式
ASP.NET Core Web API设置响应输出的Json数据格式的两种方式
|
5月前
|
存储 缓存 NoSQL
缓存面试解析:穿透、击穿、雪崩,一致性、分布式锁、Redis过期,海量数据查找
本文提供了一些保证数据一致性和设计分布式锁的策略。这些策略可以在实际应用中帮助开发人员解决相关的问题,确保系统的数据一致性和并发访问的正确性。同时,通过合理地使用缓存和分布式锁,可以提高系统的性能和可靠性。希望对你在面对Redis相关面试题时有所帮助!
377 0
|
6月前
|
缓存 NoSQL 算法
Redis之过期key的淘汰及缓存淘汰策略解读
Redis之过期key的淘汰及缓存淘汰策略解读
|
6月前
|
存储 缓存 NoSQL
Redis第一讲:相关的基础知识/数据类型/缓存的过期策略/双写一致性/内存存储和持久化
Redis第一讲:相关的基础知识/数据类型/缓存的过期策略/双写一致性/内存存储和持久化
|
7月前
|
存储 缓存 前端开发
Web Server 设置缓存响应字段的一些推荐方案
Web Server 设置缓存响应字段的一些推荐方案
48 1
|
7月前
|
缓存 安全 PHP
SAP Gateway 后台模型的缓存设置
SAP Gateway 后台模型的缓存设置
47 0

热门文章

最新文章