最近在網上瀏覽到一篇關於.net的緩存的知識,講解的挺詳細的,對於最近這個剛入門者來講仍是挺有價值的,記錄一下,以供學習. 數據庫
動態網站的好處就是信息能夠隨時更新,跟用戶交互的功能,可是大部分的動態網站都是隻須要把信息提交上去後,而後就沒有或者不多須要更新的,用戶在請求這些頁面內容的時候,每次都要讀取數據庫,若是用戶不少的狀況下,就會給服務器帶來壓力,甚至會癱瘓。遇到這樣的狀況,人們想出了不少解決的辦法,有生成靜態頁面的(好比 一些新聞系統,文章錄入後就再也不須要更新的了或者極少更新的)、或者使用緩存技術的。數組
ASP.NET提供三種主要形式的緩存:頁面級輸出緩存、用戶控件級輸出緩存(或稱爲片斷緩存)和緩存API。輸出緩存和片斷緩存的優勢是很是易於實現,在大多數狀況下,使用這兩種緩存就足夠了。而緩存API則提供了額外的靈活性(其實是至關大的靈活性),可用於在應 用程序的每一層利用緩存。本文全面介紹了這三種緩存技術在系統各層中的應用。 在ASP.NET提供的許多特性中,緩存支持無疑是我最欣賞的特性,我這樣說固然是有充分理由的。相比ASP.NET的全部其餘特性,緩存對應用程序的性能具備最大的潛在影響,利用緩存和其餘機制,ASP.NET開發人員能夠接受使用開銷很大的控件(例如,DataGrid)構建站點時的額外開銷,而沒必要擔憂性能會受到太大的影響。爲了在應用程序中最大程度地利用緩存,您應該考慮在全部程序級別上都實現緩存的方法。瀏覽器
頁面級輸出緩存緩存
做爲最簡單的緩存形式,輸出緩存只是在內存中保留爲響應請求而發送的HTML的副本。其後再有請求時將提供緩存的輸出,直到緩存到期,這樣,性能有可能獲得很大的提升(取決於須要多少開銷來建立原始頁面輸出-發送緩存的輸出老是很快,而且比較穩定)。服務器
實現ide
要實現頁面輸出緩存,只要將一條OutputCache指令添加到頁面便可。佈局
<%@ OutputCache Duration="60" VaryByParam="*" %>性能
如同其餘頁面指令同樣,該指令應該出如今ASPX頁面的頂部,即在任何輸出以前。它支持五個屬性(或參數),其中兩個是必需的。Duration 必需屬性。頁面應該被緩存的時間,以秒爲單位。必須是正整數。 Location 指定應該對輸出進行緩存的位置。若是要指定該參數,則必須是下列選項之一:Any、Client、Downstream、None、Server或ServerAndClient。VaryByParam 必需屬性。Request中變量的名稱,這些變量名應該產生單獨的緩存條目。「none」表示沒有變更。「*」可用於爲每一個不一樣的變量數組建立新的緩存條目。變量之間用「;」進行分隔。VaryByHeader 基於指定的標頭中的變更改變緩存條目。VaryByCustom 容許在global.asax中指定自定義變更(例如,「Browser」)。利用必需的Duration和VaryByParam選項的組合能夠處理大多數狀況。例如,若是您的產品目錄容許用戶基於categoryID和頁變量查看目錄頁,您能夠用參數值爲「categoryID;page」的VaryByParam將產品目錄緩存一段時間(若是產品不是隨時都在改變,一小時仍是能夠接受的,所以,持續時間是3600秒)。這將爲每一個種類的每一個目錄頁建立單獨的緩存條目。每一個條目從其第一個請求算起將維持一個小時。VaryByHeader和VaryByCustom主要用於根據訪問頁面的客戶端對頁面的外觀或內容進行自定義。同一個URL可能須要同時爲瀏覽器和移動電話客戶端呈現輸出,所以,須要針對不一樣的客戶端緩存不一樣的內容版本。或者,頁面有可能已經針對IE進行了優化,針對Netscape或Opera則應取消這種優化功能。後一個例子很是廣泛,咱們將提供一個說明如何實現此目標的示例:學習
示例:VaryByCustom用於支持瀏覽器自定義測試
爲了使每一個瀏覽器都具備單獨的緩存條目,VaryByCustom的值能夠設置爲「browser」。此功能已經內置在緩存模塊中,而且將針對每一個瀏覽器名稱和主要版本插入單獨的頁面緩存版本。
<%@ OutputCache Duration="60" VaryByParam="None" VaryByCustom="browser"%>
片斷緩存,用戶控件輸出緩存
緩存整個頁面一般並不可行,由於頁面的某些部分是針對用戶定製的。不過,頁面的其餘部分是整個應用程序共有的。這些部分最適合使用片斷緩存和用戶控件進行緩存。此外,菜單和其餘佈局元素,尤爲是那些從數據源動態生成的元素,也能夠用這種方法進行緩存。若是須要,能夠按如下條件選擇須要緩存的控件:
(1)某控件的屬性已改變
(2)由頁面級輸出緩存所支持的任何一種頁面或控件狀態改變
一旦對某些控件進行了緩存,使用它們的幾百個頁面就能夠共享這些控件,而再也不須要爲每一個頁面保留單獨的控件緩存版本。
實現
片斷緩存使用的語法與頁面級輸出緩存同樣,但其應用於用戶控件(.ascx文件)而不是Web窗體(.aspx文件)。除了Location屬性,對於OutputCache在Web窗體上支持的全部屬性,用戶控件也一樣支持。用戶控件還支持名爲VaryByControl的OutputCache屬性,該屬性將根據用戶控件(一般是頁面上的控件,例如,DropDownList)的成員的值改變該控件的緩存。若是指定了VaryByControl,能夠省略VaryByParam。最後,在默認狀況下,對每一個頁面上的每一個用戶控件都單獨進行緩存。不過,若是一個用戶控件不隨應用程序中的頁面改變,而且在全部頁面都使用相同的名稱,則能夠設置參數Shared的值爲「true」,該參數將使用戶控件的緩存版本供引用該控件的全部頁面使用。
示例
<%@ OutputCache Duration="60" VaryByParam="*" %>
該示例將緩存用戶控件60秒,而且將針對查詢字符串的每一個變更、針對此控件所在的每一個頁面建立單獨的緩存條目。
<%@ OutputCache Duration="60" VaryByParam="none" VaryByControl="CategoryDropDownList" %>
該示例將緩存用戶控件60秒,而且將針對CategoryDrop,DownList控件的每一個不一樣的值、針對此控件所在的每一個頁面建立單獨的緩存條目。
<%@ OutputCache Duration="60" VaryByParam="none" VaryByCustom="browser"
Shared="true" %>
最後,該示例將緩存用戶控件60秒,而且將針對每一個瀏覽器名稱和主要版本建立一個緩存條目。而後,每一個瀏覽器的緩存條目將由引用此用戶控件的全部頁面共享(只要全部頁面都用相同的ID引用該控件便可)。
緩存API,使用Cache對象
頁面級和用戶控件級輸出緩存的確是一種能夠迅速而簡便地提升站點性能的方法,可是在ASP.NET中,緩存的真正靈活性和強大功能是經過Cache對象提供的。使用Cache對象,您能夠存儲任何可序列化的數據對象,基於一個或多個依賴項的組合來控制緩存條目到期的方式。這些依賴項能夠包括自從某對象被緩存後通過的時間、自從某對象上次被訪問後通過的時間、對文件或文件夾的更改以及對其餘緩存對象的更改,在略做處理後還能夠包括對數據庫中特定表的更改。
在Cache中存儲數據
在Cache中存儲數據的最簡單的方法就是使用一個鍵爲其賦值,就像HashTable或Dictionary對象同樣:
Cache["key"] = "value";
這種作法將在緩存中存儲項,同時不帶任何依賴項,所以它不會到期,除非緩存引擎爲了給其餘緩存數據提供空間而將其刪除。要包括特定的緩存依賴項,可以使用Add()或Insert()方法。其中每一個方法都有幾個重載。Add()和Insert()之間的惟一區別是,Add()返回對已緩存對象的引用,而Insert()沒有返回值(在C#中爲空,在VB中爲Sub)。
示例
Cache.Insert("key", myXMLFileData, new
System.Web.Caching.CacheDependency(Server.MapPath("users.xml")));
該示例可將文件中的xml數據插入緩存,無需在之後請求時從文件讀取。CacheDependency的做用是確保緩存在文件更改後當即到期,以即可以從文件中提取最新數據,從新進行緩存。若是緩存的數據來自若干個文件,還能夠指定一個文件名的數組。
Cache.Insert("dependentkey", myDependentData, new
System.Web.Caching.CacheDependency(new string[] {}, new string[]
{"key"}));
該示例可插入鍵值爲「key」的第二個數據塊(取決因而否存在第一個數據塊)。若是緩存中不存在名爲「key」的鍵,或者若是與該鍵相關聯的對象已到期或被更新,則「dependentkey」的緩存條目將到期。
Cache.Insert("key", myTimeSensitiveData, null,
DateTime.Now.AddMinutes(1), TimeSpan.Zero);
絕對到期:此示例將對受時間影響的數據緩存一分鐘,一分鐘事後,緩存將到期。注意,絕對到期和滾動到期(見下文)不能一塊兒使用。
Cache.Insert("key", myFrequentlyAccessedData, null, System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(1));
動態滾動到期:此示例將緩存一些頻繁使用的數據。數據將在緩存中一直保留下去,除非數據未被引用的時間達到了一分鐘。注意,動態滾動到期和絕對到期不能一塊兒使用。
緩存數據引用模式
每當咱們嘗試訪問緩存中的數據時,都應該考慮到一種狀況,那就是數據可能已經不在緩存中了。所以,下面的模式應該廣泛適用於您對緩存的數據的訪問。在這種狀況下,咱們假定已緩存的數據是一個數據表。
public DataTable GetCustomers(bool BypassCache)
{
string cacheKey = "CustomersDataTable";
object cacheItem = Cache[cacheKey] as DataTable;
if((BypassCache) || (cacheItem == null))
{
cacheItem = GetCustomersFromDataSource();
Cache.Insert(cacheKey, cacheItem, null,
DateTime.Now.AddSeconds(GetCacheSecondsFromConfig(cacheKey), TimeSpan.Zero);
}
return (DataTable)cacheItem;
}
關於此模式,有如下幾點須要注意:
1) 某些值(例如,cacheKey、cacheItem和緩存持續時間)是一次定義的,而且只定義一次。
2) 能夠根據須要跳過緩存-例如,當註冊一個新客戶並重定向到客戶列表後,最好的作法可能就是跳過緩存,用最新數據從新填充緩存,該數據包括新插入的客戶。
3) 緩存只能訪問一次。這種作法能夠提升性能,並確保不會發生NullReferenceExceptions,由於該項在第一次被檢查時是存在的,但第二次檢查以前就已經到期了。
4) 該模式使用強類型檢查。C#中的「as」運算符嘗試將對象轉換爲類型,若是失敗或該對象爲空,則只返回null(空)。
5) 持續時間存儲在配置文件中。在理想的狀況下,全部的緩存依賴項(不管是基於文件的,或是基於時間的,仍是其餘類型的依賴項)都應該存儲在配置文件中,這樣就能夠進行更改並輕鬆地測量性能。我還建議您指定默認緩存持續時間,並且,若是沒有爲所使用的cacheKey指定持續時間,就讓GetCacheSecondsFromConfig()方法使用該默認持續時間。
小結
緩存可使應用程序的性能獲得很大的提升,所以在設計應用程序以及對應用程序進行性能測試時應該予以考慮。應用程序總會或多或少地受益於緩存,固然有些應用程序比其餘應用程序更適合使用緩存。對ASP.NET提供的緩存選項的深入理解是任何ASP.NET開發人員應該掌握的重要技巧。