[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
如果你想及時得到個人撰寫文章以及著作的消息推送,或者想看看個人推薦的技術資料,可以掃描左邊二維碼(或者長按識別二維碼)關注個人公眾號(原來公眾帳號蔣金楠的自媒體將會停用)。
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁麵明顯位置給出原文連接,否則保留追究法律責任的權利。
最後更新:2017-10-25 15:03:54