緩存二、HttpRuntime.Cache用法


上一篇寫了Asp.net頁面緩存,本篇介紹在服務器端進行緩存。微軟.net給我提供了HttpRuntime.Cache對象進行緩存。個人對緩存的理解是,將從數據庫、文件、或業務邏輯計算出來的數據,保存在內存中,當下一次遇到相同內容的請求就直接將保存在內存中的數據返回給請求者。這樣做的好處是可以提高訪問效率,減少文件或是數據庫的讀取,屬於"以空間換時間",適當的運用好Cache可以很大程度提高程序性能。關於Cache本文所包含的內容有

  • Page.Cache,HttpRuntime.Cache,HttpContext.Current.Cache的區別
  • Cache用法
  • Cache項依賴關系

一、Page.CacheHttpRuntime.CacheHttpContext.Current.Cache的區別

在代碼中可以通過以Page.CacheHttpRuntime.CacheHttpContext.Current.Cache三種方式引用到Cache對象,那這三種方式有什么區別呢,在網上查詢了相關文檔后,通過Reflect實踐查看,找出具體代碼。為便於理解,先看以下Reflect中截圖:

1HttpContext.Current.Cache

2Page.Cache

   

3HttpRuntime.Cache

   

通過Reflect代碼查看器,可以確定的是HttpContext. Current.Cache指向的是HttpRuntime.Cache。而Page.Cache指向的是一個內部變量internal Cache _cache;為什么說這里是指向HttpContext.Current.Cache?本人猜測是因為this指向的是HttpContext.Current,不知是否正確,希望園友指點,謝謝!

需要注意的是在Asp.netHttpRuntime.Cache為靜態對象,方便我們調用,一般直接用HttpRunTime.Cache就可以。

 

二、Cache用法

從元數據中查看Cache主要有Add/Get/Insert/Remove等方法,Add方法只有一個,Insert方法卻有多個重載這是為什么呢?我們還是通過Reflect查看代碼實現,來了解它們之間的區別。先查看Add方法的代碼,從下圖中可以看到,Add調用的是return this._cacheInternal.DoInsert方法

再來看Insert方法,居然也是調用this._cacheInternal.DoInsert方法,兩者的唯一區別是,Add函數是有返回而Insert的是無返回的。

對於Add函數返回值,微軟是這樣解釋的:如果該項先前存儲在 Cache 中,則為 System.Object,否則為 null也就是第一次的添加key至緩存時,返回為null,而以后再執行Add方法添加同一key時返回的是第一次Add的值。 結合之前我在博客園里看到的文章,指出Add方法添加緩存時,如果Key已存在是不修改原來的值,沒有做任何修改,查詢Cache.Count也沒有增加。那我們用Add函數編程時是要根據返回nullObject來判斷當前Key是否已存在嗎?我們來寫測試代碼,通過Add方法重復添加兩個Key值,再查看返回值的變化。

我們通過代碼來測試:

static void Main(string[] args) { string str1 = "I'm str1"; //第一次通過Add方法加入Key[str1] //返回值:null object obj1 = HttpRuntime.Cache.Add("str1", str1, null, DateTime.MaxValue, TimeSpan.Zero, CacheItemPriority.Default, null); //value1=I'm str1 string value = HttpRuntime.Cache.Get("str1").ToString(); //第二次通過Add方法加入Key[str1] //返回值:I'm str1 object obj2 = HttpRuntime.Cache.Add("str1", "hello i'm str2!", null, DateTime.MaxValue, TimeSpan.Zero, CacheItemPriority.Default, null); //value2=I'm str1 string value2 = HttpRuntime.Cache.Get("str1").ToString(); //通過Insert方法添加Key[str1] HttpRuntime.Cache.Insert("str1", "hello i'm str3 by insert!"); //value3=hello i'm str3 by insert! string value3 = HttpRuntime.Cache.Get("str1").ToString(); }

上面的代碼,我把Key=str1的對象執行了兩次Add函數一次Insert函數,執行結果表明,當第一次調用Add時,是向Cache里寫入一個值,並且返回的是null。第二次調用Add時返回的是第一次寫入的值。第三次調用Insert時把第一次寫入的值給覆蓋了,至此AddInsert的區別已經清楚了,結果請查看以下截圖:

 

三、緩存項依賴關系

CacheDependency

緩存項依賴關系,是很有用的一個功能,它是與自定議的緩存對象的一大區別(如靜態對象),不需要自已寫邏輯去維護緩存的失效。比如有兩個緩存項key1、key2,當key1值變化時,key2自動失效,我們通過以下代碼來實現這個功能:

static void Main(string[] args) { //創建兩個緩存,並且key2依賴於key1,當key1發生改變時,key2失效 HttpRuntime.Cache.Insert("key1", "key1-1"); CacheDependency dep = new CacheDependency(null, new string[] { "key1" }); HttpRuntime.Cache.Insert("key2", "key2-1", dep, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration); Console.WriteLine("key1=" + HttpRuntime.Cache.Get("key1")); Console.WriteLine("key2=" + HttpRuntime.Cache.Get("key2")); Console.WriteLine("\n修改key1值:"); HttpRuntime.Cache.Insert("key1", "key1-2"); Console.WriteLine("key1=" + HttpRuntime.Cache.Get("key1")); Console.WriteLine("key2=" + HttpRuntime.Cache.Get("key2")); //Console.WriteLine("\n修改key2值:"); //HttpRuntime.Cache.Insert("key2", "key2-2"); //Console.WriteLine("key1=" + HttpRuntime.Cache.Get("key1")); //Console.WriteLine("key2=" + HttpRuntime.Cache.Get("key2"));  Console.ReadLine(); }

上面說的是緩存項的依賴,也可以設置緩存對於文件的依賴。在實際應用中,用於根據文件內容計算了一個MD5值當文件內容改變時,讓緩存失效重新計算MD5。也可用於緩存XMLwebConfig文件,當值改變時讓緩存失效。下面給出樣例代碼,把txt作為緩存對象,當內容變更時,實現緩存失效重新讀取文件內容。

static void Main(string[] args) { //文件路徑 string path = System.Environment.CurrentDirectory; int i = path.IndexOf("bin"); path = Path.Combine(path.Substring(0, i), "time.txt"); //讀取文件內容 string content = ""; using (StreamReader sr = new StreamReader(File.OpenRead(path))) { content = sr.ReadToEnd(); } CacheDependency dep = new CacheDependency(path); //1.寫入緩存 HttpRuntime.Cache.Insert("key1", DateTime.Now, dep); //2.讀取緩存 Console.WriteLine("緩存項key1=" + HttpRuntime.Cache.Get("key1")); //3.修改文件 Console.WriteLine("\n在文件中添加內容!\n"); using (StreamWriter sw = File.AppendText(path)) { sw.Write("\n" + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.ffff") + "\n"); } //4.讀取緩存 Thread td = new Thread(delegate() { Thread.Sleep(1000); Console.WriteLine("緩存項key1=" + HttpRuntime.Cache.Get("key1")); }); td.Start(); Console.ReadLine(); }

 

在文件內容被修改后,可以看到再次讀取key1時值為空了(如下圖)。在第三步向文件中添加內容后,再次讀取緩存時緩存已失效了。這樣就達到了讓緩存項依賴於文件目的。

CacheDependency也可以同時指定依賴文件、依賴緩存項、還可以依賴於另一個緩存依賴項。用法很多,在實際應用中根據不同情況指定依賴對象,需要我們自己去發現及體會,如果用的恰當,可以為我們省下許多判斷代碼,並提升程序性能。

//檢查依賴多個文件,也依賴多個緩存鍵值 CacheDependency mydep = new CacheDependency(new string[] { "data.xml", "data1.xml" }, new string[] { "Category", "Category1" }); //關聯依賴,還可以依賴於另一個文件緩存依賴 CacheDependency mydep2 = new CacheDependency(new string[] { "data.xml", "data1.xml" }, new string[] { "Category", "Category1" }, mydep);

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM