一般,應用程序能夠將那些頻繁訪問的數據,以及那些須要大量處理時間來建立的數據存儲在內存中,從而提升性能。例如,若是應用程序使用複雜的邏輯來處理大量數據,而後再將數據做爲用戶頻繁訪問的報表返回,避免在用戶每次請求數據時從新建立報表能夠提升效率。一樣,若是應用程序包含一個處理複雜數據但不須要常常更新的頁,則在每次請求時服務器都從新建立該頁會使工做效率低下。
在這些狀況下,爲了幫助您提升應用程序的性能,ASP.NET 使用兩種基本的緩存機制來提供緩存功能。第一種機制是應用程序緩存,它容許您緩存所生成的數據,如 DataSet 或自定義報表業務對象。第二種機制是頁輸出緩存,它保存頁處理輸出,並在用戶再次請求該頁時,重用所保存的輸出,而不是再次處理該頁。
應用程序緩存
應用程序緩存提供了一種編程方式,可經過鍵/值對將任意數據存儲在內存中。使用應用程序緩存與使用應用程序狀態相似。可是,與應用程序狀態不一樣的是,應用程序緩存中的數據是易失的,即數據並非在整個應用程序生命週期中都存儲在內存中。使用應用程序緩存的優勢是由 ASP.NET 管理緩存,它會在項過時、無效、或內存不足時移除緩存中的項。還能夠配置應用程序緩存,以便在移除項時通知應用程序。有關更多信息,請參見緩存應用程序數據。
使用應用程序緩存的模式是,肯定在訪問某一項時該項是否存在於緩存中,若是存在,則使用。若是該項不存在,則能夠從新建立該項,而後將其放回緩存中。這一模式可確保緩存中始終有最新的數據。
有關更多信息,請參見如何:檢索緩存項的值。
頁輸出緩存
頁輸出緩存在內存中存儲處理後的 ASP.NET 頁的內容。這一機制容許 ASP.NET 向客戶端發送頁響應,而沒必要再次通過頁處理生命週期。頁輸出緩存對於那些不常常更改,但須要大量處理才能建立的頁特別有用。例如,若是建立大通訊量的網頁來顯示不須要頻繁更新的數據,頁輸出緩存則能夠極大地提升該頁的性能。能夠分別爲每一個頁配置頁緩存,也能夠在 Web.config 文件中建立緩存配置文件。利用緩存配置文件,只定義一次緩存設置就能夠在多個頁中使用這些設置。
頁輸出緩存提供了兩種頁緩存模型:整頁緩存和部分頁緩存。整頁緩存容許將頁的所有內容保存在內存中,並用於完成客戶端請求。部分頁緩存容許緩存頁的部份內容,其餘部分則爲動態內容。有關更多信息,請參見緩存 ASP.NET 頁。
部分頁緩存可採用兩種工做方式:控件緩存和緩存後替換。控件緩存有時也稱爲分段緩存,這種方式容許將信息包含在一個用戶控件內,而後將該用戶控件標記爲可緩存的,以此來緩存頁輸出的部份內容。這一方式可緩存頁中的特定內容,並不緩存整個頁,所以每次都需從新建立整個頁。例如,若是要建立一個顯示大量動態內容(如股票信息)的頁,其中有些部分爲靜態內容(如每週總結),這時能夠將靜態部分放在用戶控件中,並容許緩存這些內容。
緩存後替換與控件緩存正好相反。這種方式緩存整個頁,但頁中的各段都是動態的。例如,若是要建立一個在規定時間段內爲靜態的頁,則能夠將整個頁設置爲進行緩存。若是向頁添加一個顯示用戶名的 Label控件,則對於每次頁刷新和每一個用戶而言,Label 的內容都將保持不變,始終顯示緩存該頁以前請求該頁的用戶的姓名。可是,使用緩存後替換機制,能夠將頁配置爲進行緩存,但將頁的個別部分標記爲不可緩存。在此狀況下,能夠向不可緩存部分添加 Label 控件,這樣將爲每一個用戶和每次頁請求動態建立這些控件。有關更多信息,請參見緩存 ASP.NET 頁的某些部分。
根據請求參數緩存頁
除緩存頁的單一版本外,ASP.NET 頁輸出緩存還提供了一些功能,能夠建立根據請求參數的不一樣而不一樣的頁的多個版本。有關更多信息,請參見緩存頁的多個版本。
自動移除數據
出於如下緣由之一,ASP.NET 能夠從緩存中移除數據:
-
因爲服務器上的內存不足,開始一個稱爲「清理」的過程。
-
因爲緩存中的項已過時。
-
因爲項的依賴項發生了更改。
爲了幫助管理緩存項,在將項從緩存中移除時,ASP.NET 會通知應用程序。
清理
清理是在內存不足時從緩存中刪除項的過程。若是某些項在一段時間內未被訪問,或是在添加到緩存中時被標記爲低優先級,則這些項會被移除。ASP.NET 使用 CacheItemPriority 對象來肯定要首先清理的項。有關更多信息,請參見如何:將項添加到緩存中。
過時
除了清理外,在緩存項過時時,ASP.NET 會自動從緩存中移除這些項。向緩存添加項時,能夠按下表中的描述設置其過時時間。
過時類型 | 說明 |
---|---|
可調過時 |
指定某項自上次被訪問後多長時間過時。例如,能夠將某項設置爲自上次在緩存中被訪問後 20 分鐘過時。 |
絕對過時 |
指定某項在設定的時間過時,而不考慮訪問頻率。例如,能夠將某項設置爲在 6:00 PM 過時,或四小時後過時。 |
依賴項
能夠將緩存中某一項的生存期配置爲依賴於其餘應用程序元素,如某個文件或數據庫。當緩存項依賴的元素更改時,ASP.NET 將從緩存中移除該項。例如,若是您的網站顯示一份報告,該報告是應用程序經過 XML 文件建立的,您能夠將該報告放置在緩存中,並將其配置爲依賴於該 XML 文件。當 XML 文件更改時,ASP.NET 會從緩存中移除該報告。當代碼請求該報告時,代碼會先肯定該報告是否在緩存中,若是不在,代碼會從新建立該報告。所以,始終都有最新版本的報告可用。
ASP.NET 緩存支持下表中描述的依賴項。
依賴項 | 說明 |
---|---|
鍵依賴項 |
應用程序緩存中的項存儲在鍵/值對中。鍵依賴項容許項依賴於應用程序緩存中另外一項的鍵。若是移除了原始項,則具備鍵依賴關係的項也會被移除。例如,能夠添加一個名爲 ReportsValid 的緩存項,而後緩存若干個依賴於 ReportsValid 鍵的報告。當 ReportsValid 項被移除時,全部依賴於它的緩存報告一樣也會從緩存中移除。 |
文件依賴項 |
緩存中的項依賴於外部文件。若是該文件被修改或刪除,則緩存項也會被移除。 |
SQL 依賴項 |
緩存中的項依賴於 Microsoft SQL Server 200五、SQL Server 2000 或 SQL Server 7.0 數據庫中表的更改。對於 SQL Server 2005,緩存中的項可依賴於表中的某一行。有關更多信息,請參見使用 SqlCacheDependency 類在 ASP.NET 中緩存。 |
聚合依賴項 |
經過使用 AggregateCacheDependency 類緩存中的項依賴於多個元素。若是任何依賴項發生更改,該項都會從緩存中移除。 |
自定義依賴項 |
能夠用您本身的代碼建立的依賴關係來配置緩存中的項。例如,能夠建立一個自定義 Web 服務緩存依賴項,當調用 Web 服務獲得一個特定值時,該依賴項就會從緩存中移除數據。 |
應用程序緩存項移除通知
當項從應用程序緩存中移除時,您能夠收到通知。例如,若是有一個須要大量處理時間才能建立的項,當從緩存中移除該項時,您會收到通知以即可以當即替換該項。這樣,下次請求該項時,用戶便沒必要等待處理該項。有關更多信息,請參見如何:從緩存中移除項時通知應用程序。
ASP.NET 2.0 版保留了 ASP.NET 1.1 版的全部緩存功能,同時添加了新功能並加強了現有功能。新功能包括緩存配置文件、自定義緩存依賴項、SQL 緩存依賴項以及在緩存頁中建立動態內容(緩存後替換)。加強功能包括功能更強大的部分頁(控件)緩存模型、加強的緩存配置以及輸出緩存指令的改進。
新緩存功能
緩存配置文件
緩存配置文件使您可以在應用程序的 Web.config 文件中建立緩存設置,而後在單個頁上引用這些設置。這使您可以將緩存設置同時應用於多頁。例如,能夠定義一個名爲 DailyUpdate 的緩存配置文件,它將頁的緩存持續時間設置爲一天。而後能夠配置各個頁使用 DailyUpdate 緩存配置文件,而且這些頁的緩存持續時間爲一天。若是將 DailyUpdate 緩存配置文件更改成不使用緩存,將中止緩存這些頁。有關更多信息,請參見 ASP.NET 中的緩存配置。
自定義緩存依賴項
在 ASP.NET 2.0 中,您能夠根據應用程序特定狀況建立本身的自定義緩存依賴項。若要建立自定義緩存依賴項,請建立從 CacheDependency 繼承的類並在自定義類中實現您本身的依賴項方法。例如,您能夠建立在 Web 服務中輪詢數據的依賴項;當數據發生變化時,您可使緩存數據無效。若要了解經過指定依賴項向緩存添加項目的信息,請參見如何:將項添加到緩存中。
SqlCacheDependency
ASP.NET 2.0 引入了 SqlCacheDependency 類,它使您可以在緩存中配置一個項,以便在 Microsoft SQL Server 數據庫中的表或行上擁有依賴項。當表中或特定行中發生更改時,具備依賴項的緩存項便會失效並從緩存中移除。ASP.NET 2.0 使您可以在 SQL Server 7.0、SQL Server 2000 和 SQL Server 2005 中設置表的依賴項。使用 SQL Server 2005 時,您還能夠設置特定記錄的依賴項。有關更多信息,請參見使用 SqlCacheDependency 類在 ASP.NET 中緩存。
緩存後替換
ASP.NET 2.0 如今支持緩存後替換,使您可以將頁中的某一部分配置爲不可緩存。所以,儘管緩存了該頁,但在再次請求該頁時,將從新處理它的部份內容。例如,您可使用大多數靜態內容(但不能使用在Label 控件中顯示用戶名的內容)建立緩存頁。若是不使用緩存後替換,用戶名在全部請求中保持不變。若是使用緩存後替換,您能夠將頁標記爲可緩存,而後將 Label 控件放置在標記爲不可緩存的另外一個控件中。此後每次請求該頁時,都會刷新用戶名。有關更多信息,請參見緩存 ASP.NET 頁的某些部分。
緩存加強
控件緩存
在 ASP.NET 1.1 中,經過設置 @ Control 指令中的參數以聲明方式配置用戶控件緩存。在 ASP.NET 2.0 中,能夠在運行時使用 CachePolicy 對象配置用戶控件緩存設置。CachePolicy 對象使您可以按照以編程方式處理頁輸出緩存的相同方式處理用戶控件緩存。有關更多信息,請參見緩存 ASP.NET 頁的某些部分。
緩存配置加強
除了緩存配置文件外,ASP.NET 2.0 中還引入了新的緩存配置設置,能夠在應用程序的 Web.config 文件中指定這些設置。這些設置增長了您對緩存的控制,如內存使用量和緩存清理行爲。有關更多信息,請參見 ASP.NET 中的緩存配置。
輸出緩存指令改進
ASP.NET 2.0 包括新的 @ OutputCache 指令選項以及對現有選項的加強。新功能和加強功能使您可以對輸出緩存功能進行聲明控制,而之前只能使用 HttpCachePolicy 類以編程方式實現此類控制。例如,如今能夠用聲明方式設置頁 @ OutputCache 指令中的 Duration 屬性和 NoStore 屬性。有關更多信息,請參見設置頁的可緩存性。
ASP.NET 爲您提供了一個強大的、便於使用的緩存機制,用於將須要大量服務器資源來建立的對象存儲在內存中。緩存這些類型的資源會大大改進應用程序的性能。
緩存是由 Cache 類實現的;緩存實例是每一個應用程序專用的。緩存生存期依賴於應用程序的生存期;從新啓動應用程序後,將從新建立 Cache 對象。
設計 Cache 類是爲了便於使用。您能夠將項放置在 Cache 中,並在之後使用簡單的鍵/值對來檢索這些項。有關如何執行此操做的示例,請參見如何:將項添加到緩存中和如何:檢索緩存項的值。
Cache 類提供了強大的功能,容許您自定義如何緩存項以及將它們緩存多長時間。例如,當缺少系統內存時,緩存會自動移除不多使用的或優先級較低的項以釋放內存。該技術也稱爲清理,這是緩存確保過時數據不使用寶貴的服務器資源的方式之一。
當執行清理時,您能夠指示 Cache 給予某些項比其餘項更高的優先級。若要指示項的重要性,能夠在使用 Add 或 Insert 方法添加項時指定一個 CacheItemPriority 枚舉值。
當使用 Add 或 Insert 方法將項添加到緩存時,您還能夠創建項的過時策略。您能夠經過使用DateTime 值指定項的確切過時時間(絕對過時時間),來定義項的生存期。也可使用 TimeSpan 值指定一個彈性過時時間,彈性過時時間容許您根據項的上次訪問時間來指定該項過時以前的運行時間。一旦項過時,便將它從緩存中移除。試圖檢索它的值的行爲將返回 null(在 Visual Basic 中爲Nothing),除非該項被從新添加到緩存中。
對於存儲在緩存中的易失項(例如那些按期進行數據刷新的項或那些只在一段時間內有效的項),一般設置一種過時策略:只要這些項的數據保持爲最新的,就將它們保留在緩存中。例如,若是您正在編寫一個應用程序,該應用程序經過另外一個網站獲取數據來跟蹤體育比賽的比分,那麼只要源網站上比賽的比分不更改,就能夠緩存這些比分。在此狀況下,您能夠根據其餘網站更新比分的頻率來設置過時策略。您能夠編寫代碼來肯定緩存中是不是最新的比分。若是該比分不是最新的,則代碼能夠從源網站讀取比分並緩存新值。
最後,ASP.NET 容許您根據外部文件、目錄(文件依賴項)或另外一個緩存項(鍵依賴項)來定義緩存項的有效性。若是具備關聯依賴項的項發生更改,緩存項便會失效並從緩存中移除。您可使用該技術在項的數據源更改時從緩存中移除這些項。例如,若是您編寫一個處理 XML 文件中的財務數據的應用程序,則能夠從該文件將數據插入緩存中並在此 XML 文件上保留一個依賴項。當該文件更新時,從緩存中移除該項,您的應用程序從新讀取 XML 文件,而後將刷新後的數據放入緩存中。
![]() |
---|
Cache 對象沒有關於它所包含項的內容的信息。它只保留對這些對象的引用。它還提供跟蹤它們的依賴項和設置到期策略的方法。
ASP.NET 中的緩存配置
ASP.NET 提供了許多可用於配置頁面輸出緩存和緩存 API 的選項。能夠在處理了頁面響應後使用頁面輸出緩存來緩存此頁面響應。也能夠經過編程的方式使用緩存 API 來緩存應用程序數據。有關更多信息,請參見 ASP.NET 緩存概述。 頁面輸出緩存配置您能夠在如下這些位置配置頁面輸出緩存:
Web.config 緩存配置設置在 Web.config 文件中,有兩個頂級配置節可用於頁輸出緩存:OutputCacheSection 和OutputCacheSettingsSection。 OutputCacheSection 節用於配置應用程序範圍的設置,例如是啓用仍是禁用頁輸出緩存。例如,您能夠經過向 Web.config 文件中的 OutputCacheSection 添加 enableOutputCache="false" 來對整個應用程序禁用頁輸出緩存。因爲配置文件中的設置要優先於單個頁面中的緩存設置,所以,示例設置將致使不使用輸出緩存。 OutputCacheSettingsSection 用於配置可由單個頁使用的配置文件和依賴項。例如,下面的代碼建立了一個名爲 CacheProfile1 的 OutputCacheProfile,它將緩存實現頁 60 秒: <outputCacheSettings> <outputCacheProfiles> <add name="CacheProfile1" duration="60" /> </outputCacheProfiles> </outputCacheSettings> Machine.config 緩存配置設置Machine.config 文件的配置節與 Web.config 文件的配置節基本相同,而只有一點區別:便可以鎖定 Machine.config 文件中的配置設置,使任何級別的單個應用程序都沒法重寫這些配置設置。在宿主不但願單個應用程序修改緩存配置時,可能有必要在共享宿主方案中使用此功能。有關更多信息,請參見如何:鎖定 ASP.NET 配置設置。 頁面緩存配置設置經過應用在配置文件中定義的緩存配置文件,能夠配置單個頁中的緩存。也能夠在 @ OutputCache 指令中配置單個緩存屬性 (property),或者經過設置頁的類定義中的屬性 (attribute) 進行配置。有關更多信息,請參見 @ OutputCache 和設置頁的可緩存性。 用戶控件緩存配置設置經過設置用戶控件文件中的 @ OutputCache 指令,或設置控件類定義中的 PartialCachingAttribute屬性,能夠對用戶控件緩存進行配置。有關更多信息,請參見緩存 ASP.NET 頁的某些部分。 緩存 API 配置設置能夠在 Web.config 文件中配置應用程序的緩存 API。對於頁面輸出緩存,應用程序宿主能夠在 Machine.config 文件中設置配置屬性,並鎖定全部應用程序的緩存配置設置。應用程序緩存 API 在CacheSection 中進行配置。例如,您可使用下面的配置元素來禁用項過時: <cache disableExpiration="true" /> 還能夠經過爲屬性(如配置文件的 CacheSection 中的 DisableExpiration 和DisableMemoryCollection 屬性)賦值的方式來指定其餘應用程序緩存 API 配置設置。 |
可使用 Cache 對象訪問應用程序緩存中的項。可使用 Cache 對象的 Insert 方法嚮應用程序緩存添加項。該方法向緩存添加項,而且經過幾回重載,您能夠用不一樣選項添加項,以設置依賴項、過時和移除通知。若是使用 Insert 方法向緩存添加項,而且已經存在與現有項同名的項,則緩存中的現有項將被替換。
還可使用 Add 方法向緩存添加項。使用此方法,您能夠設置與 Insert 方法相同的全部選項;然而,Add 方法將返回您添加到緩存中的對象。另外,若是使用 Add 方法,而且緩存中已經存在與現有項同名的項,則該方法不會替換該項,而且不會引起異常。
本主題中的過程闡釋了嚮應用程序緩存添加項的以下方式:
-
經過鍵和值直接設置項,向緩存添加項。
-
使用 Insert 方法向緩存添加項。
-
向緩存添加項並添加依賴項,以便當該依賴項更改時,將該項從緩存中移除。能夠基於其餘緩存項、文件和多個對象設置依賴項。
-
將設有過時策略的項添加到緩存中。除了能設置項的依賴項之外,還能夠設置項在一段時間之後(彈性過時)或在指定時間(絕對過時)過時。您能夠定義絕對過時時間或彈性過時時間,但不能同時定義二者。
-
向緩存添加項,並定義緩存的項的相對優先級。相對優先級幫助 .NET Framework 肯定要移除的緩存項;較低優先級的項比較高優先級的項先從緩存中移除。
-
經過調用 Add 方法添加項。
除了這裏顯示的依賴項,能夠在 SQL Server 表上或基於自定義依賴項建立依賴項。有關更多信息,請參見 ASP.NET 緩存概述和使用 SqlCacheDependency 類在 ASP.NET 中緩存。
當從緩存中移除項時,還可使用 CacheItemRemovedCallback 委託讓應用程序緩存通知應用程序。有關完整示例,請參見如何:從緩存中移除項時通知應用程序。
經過鍵和值直接設置項向緩存添加項
-
經過指定項的鍵和值,像將項添加到字典中同樣將其添加到緩存中。
下面的代碼示例將名爲 CacheItem1 的項添加到 Cache 對象中:
C#Cache["CacheItem1"] = "Cached Item 1";
Visual BasicCache("CacheItem1") = "Cached Item 1"
經過使用 Insert 方法將項添加到緩存中
-
調用 Insert 方法,傳遞要添加的項的鍵和值。
下面的代碼示例添加名爲 CacheItem2 的字符串:
C#Cache.Insert("CacheItem2", "Cached Item 2");
Visual BasicCache.Insert("CacheItem2", "Cached Item 2")
經過指定依賴項向緩存添加項
-
調用 Insert 方法,將 CacheDependency 對象的一個實例傳遞給該方法
下面的代碼示例添加名爲 CacheItem3 的項,該項依賴於緩存中名爲 CacheItem2 的另外一個項:
C#string[] dependencies = { "CacheItem2" }; Cache.Insert("CacheItem3", "Cached Item 3", new System.Web.Caching.CacheDependency(null, dependencies));
Visual BasicDim dependencies As String() = {"CacheItem2"} Cache.Insert("CacheItem3", "Cached Item 3", _ New System.Web.Caching.CacheDependency( _ Nothing, dependencies))
下面的代碼示例演示將名爲 CacheItem4 的項添加到緩存中,而且在名爲 XMLFile.xml 的文件上設置文件依賴項:
C#Cache.Insert("CacheItem4", "Cached Item 4", new System.Web.Caching.CacheDependency( Server.MapPath("XMLFile.xml")));
Visual BasicCache.Insert("CacheItem4", "Cached Item 4", _ New System.Web.Caching.CacheDependency( _ Server.MapPath("XMLFile.xml")))
下面的代碼示例演示如何建立多個依賴項。它向緩存中名爲 CacheItem1 的另外一個項添加鍵依賴項,向名爲 XMLFile.xml 的文件添加文件依賴項。
C#System.Web.Caching.CacheDependency dep1 = new System.Web.Caching.CacheDependency(Server.MapPath("XMLFile.xml")); string[] keyDependencies2 = { "CacheItem1" }; System.Web.Caching.CacheDependency dep2 = new System.Web.Caching.CacheDependency(null, keyDependencies2); System.Web.Caching.AggregateCacheDependency aggDep = new System.Web.Caching.AggregateCacheDependency(); aggDep.Add(dep1); aggDep.Add(dep2); Cache.Insert("CacheItem5", "Cached Item 5", aggDep);
Visual BasicDim dep1 As CacheDependency = _ New CacheDependency(Server.MapPath("XMLFile.xml")) Dim keyDependencies2 As String() = {"CacheItem1"} Dim dep2 As CacheDependency = _ New System.Web.Caching.CacheDependency(Nothing, _ keyDependencies2) Dim aggDep As AggregateCacheDependency = _ New System.Web.Caching.AggregateCacheDependency() aggDep.Add(dep1) aggDep.Add(dep2) Cache.Insert("CacheItem5", "Cached Item 5", aggDep)
將設有過時策略的項添加到緩存中
-
調用 Insert 方法,將絕對過時時間或彈性過時時間傳遞給該方法。
下面的代碼示例將有一分鐘絕對過時時間的項添加到緩存中:
C#Cache.Insert("CacheItem6", "Cached Item 6", null, DateTime.Now.AddMinutes(1d), System.Web.Caching.Cache.NoSlidingExpiration);
Visual BasicCache.Insert("CacheItem6", "Cached Item 6", _ Nothing, DateTime.Now.AddMinutes(1.0), _ TimeSpan.Zero)
下面的代碼示例將有 10 分鐘彈性過時時間的項添加到緩存中:
C#Cache.Insert("CacheItem7", "Cached Item 7", null, System.Web.Caching.Cache.NoAbsoluteExpiration, new TimeSpan(0, 10, 0));
Visual BasicCache.Insert("CacheItem7", "Cached Item 7", _ Nothing, System.Web.Caching.Cache.NoAbsoluteExpiration, _ New TimeSpan(0, 10, 0))
將設有優先級設置的項添加到緩存中
-
調用 Insert 方法,從 CacheItemPriority 枚舉中指定一個值。
下面的代碼示例將優先級值爲 High 的項添加到緩存中:
C#Cache.Insert("CacheItem8", "Cached Item 8", null, System.Web.Caching.Cache.NoAbsoluteExpiration, System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.High, null);
Visual BasicCache.Insert("CacheItem8", "Cached Item 8", _ Nothing, System.Web.Caching.Cache.NoAbsoluteExpiration, _ System.Web.Caching.Cache.NoSlidingExpiration, _ System.Web.Caching.CacheItemPriority.High, _ Nothing)
使用 Add 方法向緩存添加項
-
調用 Add 方法,它返回一個表示項的對象。
下面的代碼示例向緩存添加名爲 CacheItem9 的項,同時將變量 CachedItem9 的值設置爲已添加的項。
C#string CachedItem9 = (string)Cache.Add("CacheItem9", "Cached Item 9", null, System.Web.Caching.Cache.NoAbsoluteExpiration, System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.Default, null);
Visual BasicDim CachedItem9 As String = CStr(Cache.Add("CacheItem9", _ "Cached Item 9", Nothing, _ System.Web.Caching.Cache.NoAbsoluteExpiration, _ System.Web.Caching.Cache.NoSlidingExpiration, _ System.Web.Caching.CacheItemPriority.Default, _ Nothing))
要從緩存中檢索數據,應指定存儲緩存項的鍵。不過,因爲緩存中所存儲的信息爲易失信息,即該信息可能由 ASP.NET 移除,所以建議的開發模式是首先肯定該項是否在緩存中。若是不在,則應將它從新添加到緩存中,而後檢索該項。
檢索緩存項的值
-
經過在 Cache 對象中進行檢查來肯定該項是否不爲 null(在 Visual Basic 中爲 Nothing)。若是該項存在,則將它分配給變量。不然,從新建立該項,將它添加到緩存中,而後訪問它。
下面的代碼示例演示如何從緩存中檢索名爲 CacheItem 的項。代碼將該項的內容分配給名爲 cachedString 的變量。若是該項不在緩存中,則代碼會將它添加到緩存中,而後將它分配給 cachedString。
C#string cachedString; cachedString = (string)Cache["CacheItem"]; if (cachedString == null) { cachedString = "Hello, World."; Cache.Insert("CacheItem", cachedString); }
Visual BasicDim cachedString As String cachedString = CStr(Cache("CacheItem")) If cachedString Is Nothing Then cachedString = "Hello, World." Cache.Insert("CacheItem", cachedString) End If
在大多數緩存方案中,當從緩存中移除項後,直到再次須要此項時,才須要將其放回緩存中。典型的開發模式是在使用項以前始終檢查該項是否已在緩存中。若是項位於緩存中,則可使用。若是不在緩存中,則應再次檢索該項,而後將其添加回緩存。
可是,在某些狀況下,若是從緩存中移除項時通知應用程序,可能很是有用。例如,您可能具備一個緩存的報告,建立該報告需花費大量的時間進行處理。當該報告從緩存中移除時,您但願從新生成該報告,並當即將其置於緩存中,以便下次請求該報告時,用戶沒必要等待對此報告進行處理。
爲了在從緩存中移除項時可以發出通知,ASP.NET 提供了 CacheItemRemovedCallback 委託。該委託定義編寫事件處理程序時使用的簽名,當對從緩存中移除項進行響應時會調用此事件處理程序。ASP.NET 還提供 CacheItemRemovedReason 枚舉,用於指定移除緩存項的緣由。
一般,經過在管理嘗試檢索的特定緩存數據的業務對象中建立處理程序,來實現回調。例如,您可能有一個 ReportManager 對象,該對象具備兩種方法,即 GetReport 和 CacheReport。GetReport 報告方法檢查緩存以查看報告是否已緩存;若是沒有,該方法將從新生成報告並將其緩存。CacheReport 方法具備與 CacheItemRemovedCallback 委託相同的函數簽名;從緩存中移除報告時,ASP.NET 會調用 CacheReport 方法,而後將報告從新添加到緩存中。
當從緩存中移除項時通知應用程序
-
建立一個類,負責從緩存中檢索項並處理回調方法,以將項添加回緩存中。
-
在該類中,建立用於將項添加到緩存中的方法。
-
在該類中,建立用於從緩存中獲取項的方法。
-
建立用於處理緩存項移除回調的方法。該方法必須具有與 CacheItemRemovedCallback 委託相同的函數簽名。從緩存中刪除項時,會在該方法中執行要運行的邏輯,如從新生成項並將其添加回緩存中。
測試緩存項回調
-
建立一個 ASP.NET 網頁,該網頁將調用類中用於將項添加到緩存中的方法。
下面的代碼示例演示如何調用 ReportManager 類的 GetReport 方法(在此過程後面的示例中定義)。而後將在使用頁面的 Page_Load 方法期間顯示 Label 控件 Label1 中的報告。
C#protected void Page_Load(object sender, EventArgs e) { this.Label1.Text = ReportManager.GetReport(); }
Visual BasicProtected Sub Page_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Me.Load Me.Label1.Text = ReportManager.GetReport() End Sub
-
在瀏覽器中請求 ASP.NET 頁並查看報告。
報告是在首次請求頁時建立的,在緩存中的報告被移除以前,後續請求都將訪問緩存中的報告。
示例
下面的代碼示例演示一個名爲 ReportManager 的、用於在從緩存中刪除項時處理通知的完整類。該類管理字符串形式的報告,此報告表示一個長期運行的進程。
儘管該示例使用聲明爲 static(在 Visual Basic 中爲 Shared)的類,但並非必須使用靜態類。不過,刪除緩存項時,用於處理回調的方法必須存在。例如,不該在 ASP.NET 頁中實現回調處理程序,由於在從緩存中刪除項以前該頁可能已被釋放,所以用於處理回調的方法將不可用。爲了確保從緩存中刪除項時處理回調的方法仍然存在,請使用該方法的靜態類。可是,靜態類的缺點是須要保證全部靜態方法都是線程安全的。
![]() |
---|
請不要在頁面中將 CacheItemRemovedCallback 設置爲一個方法。除了在釋放頁面後回調沒法使用頁面方法之外,將回調指向頁面方法還會阻礙垃圾回收將頁面使用的內存回收。因爲回調包含對頁面的引用,而垃圾回收器不會從內存中移除包含任何引用的項,所以會出現這種狀況。在加載應用程序期間,這可能會致使內存很快被用光。 |
該示例類包括如下功能:
-
私有成員,用於跟蹤報告是否已從緩存中移除。
-
名爲 CacheReport 的方法,用於將項以 MyReport 的名稱添加到緩存中,並將該項設置爲在添加到緩存中後一分鐘過時。該方法還會將 ReportRemovedCallback 方法傳遞給 onRemoveCallback 參數,從而註冊 ReportRemoveCallback 方法,以便在從緩存中刪除項時進行調用。
-
名爲 GetReport 的方法,用於從緩存中獲取項。該方法肯定名爲 MyReport 的項是否存在於緩存中。若是該項不存在,則該方法將調用 CacheReport,,將該項添加到緩存中。
-
名爲 ReportRemovedCallback 的方法,用於處理緩存項移除回調。ReportRemovedCallback 具備與 CacheItemRemovedCallback 委託相同的函數簽名。該方法將變量 _reportRemovedFromCache 設置爲 true,而後經過 CacheReport 方法將項添加回緩存中。
using System; using System.Web; using System.Web.Caching; public static class ReportManager { private static bool _reportRemovedFromCache = false; static ReportManager() { } public static String GetReport() { lock (typeof(ReportManager)) { if (HttpContext.Current.Cache["MyReport"] != null) return (string)HttpRuntime.Cache["MyReport"]; else { CacheReport(); return (string)HttpRuntime.Cache["MyReport"]; } } } public static void CacheReport() { lock (typeof(ReportManager)) { HttpContext.Current.Cache.Add("MyReport", CreateReport(), null, DateTime.MaxValue, new TimeSpan(0, 1, 0), System.Web.Caching.CacheItemPriority.Default, ReportRemovedCallback); } } private static string CreateReport() { System.Text.StringBuilder myReport = new System.Text.StringBuilder(); myReport.Append("Sales Report<br />"); myReport.Append("2005 Q2 Figures<br />"); myReport.Append("Sales NE Region - $2 million<br />"); myReport.Append("Sales NW Region - $4.5 million<br />"); myReport.Append("Report Generated: " + DateTime.Now.ToString() + "<br />"); myReport.Append("Report Removed From Cache: " + _reportRemovedFromCache.ToString()); return myReport.ToString(); } public static void ReportRemovedCallback(String key, object value, CacheItemRemovedReason removedReason) { _reportRemovedFromCache = true; CacheReport(); } }
Imports System Imports System.Web Imports System.Web.Caching Public Class ReportManager Private Shared _reportRemovedFromCache As Boolean = False Shared Sub New() End Sub Private Sub New() End Sub Public Shared Function GetReport() As String SyncLock (GetType(ReportManager)) If HttpContext.Current.Cache("MyReport") IsNot Nothing Then Return CStr(HttpRuntime.Cache("MyReport")) Else CacheReport() Return CStr(HttpRuntime.Cache("MyReport")) End If End SyncLock End Function Public Shared Sub CacheReport() SyncLock (GetType(ReportManager)) HttpContext.Current.Cache.Add("MyReport", CreateReport(), _ Nothing, DateTime.MaxValue, New TimeSpan(0, 1, 0), _ System.Web.Caching.CacheItemPriority.Default, _ AddressOf ReportRemovedCallback) End SyncLock End Sub Private Shared Function CreateReport() As String Dim myReport As New System.Text.StringBuilder() myReport.Append("Sales Report<br />") myReport.Append("2005 Q2 Figures<br />") myReport.Append("Sales NE Region - $2 million<br />") myReport.Append("Sales NW Region - $4.5 million<br />") myReport.Append("Report Generated: " & _ DateTime.Now.ToString() & "<br />") myReport.Append("Report Removed From Cache: " _ & _reportRemovedFromCache.ToString()) Return myReport.ToString() End Function Public Shared Sub ReportRemovedCallback(ByVal key As String, _ ByVal value As Object, ByVal removedReason _ As CacheItemRemovedReason) _reportRemovedFromCache = True CacheReport() End Sub End Class
ASP.NET 緩存中的數據是易失的,即不能永久保存。因爲如下任一緣由,緩存中的數據可能會自動移除:
-
緩存已滿。
-
該項已過時。
-
依賴項發生更改。
有關更多信息,請參見 ASP.NET 緩存概述。
從緩存中移除項的具體方法由用於向緩存添加項的代碼肯定。有關更多信息,請參見如何:將項添加到緩存中。項從緩存中移除時會向您發出通知。有關更多信息,請參見如何:從緩存中移除項時通知應用程序。
除了容許從緩存中自動移除項以外,還能夠顯式移除項。
![]() |
---|
若是調用 Insert 方法,並向緩存中添加與現有項同名的項,則將從緩存中刪除該舊項。 |
從緩存中顯式刪除項
ASP.NET 容許您使用 SqlCacheDependency 類建立依賴於數據庫中表或行的緩存項。當表中或特定行中發生更改時,帶有依賴項的項便會失效,並會從緩存中移除。能夠在 Microsoft SQL Server 7.0、SQL Server 2000 和 SQL Server 2005 中設置表的依賴項。若是您使用 SQL Server 2005,還能夠設置特定記錄的依賴項。
在某些方案中,使用帶有 SQL 依賴項的緩存可顯著提升應用程序的性能。例如,假定您正在構建一個從數據庫顯示產品信息的電子商務應用程序。若是不進行緩存,則每當用戶要查看產品時,應用程序都必須從數據庫請求數據。您能夠在某一時刻將產品信息緩存一天,因爲產品信息已經在內存中,所以可確保較快的響應時間,可是,當產品信息發生變化時,緩存的產品信息就會失去與數據庫中數據的同步,且不一樣步的時間最長可達一天。
使用 SQL 緩存依賴項能夠緩存產品信息,並建立一個數據庫表或行更改的依賴項。當且僅當數據更改時,基於該數據的緩存項便會失效並會從緩存中移除。下次從緩存中請求該項時,若是該項不在緩存中,即可以再次向緩存中添加更新後的版本,而且可確保具備最新的數據。
SQL 緩存依賴項還可用於頁輸出緩存。例如,能夠建立一個名爲 ViewProduct.aspx 的頁,用於顯示有關特定產品的信息。能夠將該頁的緩存策略設置爲 SQL 依賴項,就如爲手動添加到緩存中的項所設置的依賴項同樣。該頁便會一直存儲在緩存中,直至所依賴的表或行發生更改成止。當數據發生更改時,便會從新建立頁,並將新建立的頁再次存儲在輸出緩存中。
有關更多信息,請參見 ASP.NET 緩存概述。
功能
ASP.NET SQL 緩存依賴項提供如下功能:
-
SQL 緩存依賴項可用於應用程序緩存和頁輸出緩存。
-
可在 SQL Server 7.0 及更高版本中使用 SQL 緩存依賴項。
-
能夠在網絡園(一臺服務器上存在多個處理器)或網絡場(多臺服務器運行同一應用程序)中使用 SQL 緩存依賴項。
-
與 SQL 緩存依賴項關聯的數據庫操做比較簡單,所以不會給服務器帶來很高的處理成本。
-
在應用程序和 SQL Server 中配置 SQL 緩存依賴項不須要很精深的 SQL 知識。ASP.NET 中包括能夠自動執行此配置的工具。另外,還可使用 SqlCacheDependencyAdmin 類以編程方式配置 SQL 緩存依賴項。
SQL Server 7.0 和 SQL Server 2000 實現
ASP.NET 爲 SQL Server 7.0 和 SQL Server 2000 的緩存依賴項實現了一個輪詢模型。ASP.NET 進程內的一個線程會以指定的時間間隔輪詢 SQL Server 數據庫,以肯定數據是否已更改。若是數據已更改,緩存依賴項便會失效,並從緩存中移除。能夠在 Web.config 文件中以聲明方式指定應用程序中的輪詢間隔,也可使用 SqlCacheDependency 類以編程方式指定此間隔。
對於 SQL Server 7.0 和 SQL Server 2000,SQL 緩存依賴項僅限於表級別的數據更改。能夠將 ASP.NET 配置爲輪詢數據庫來肯定表中的更改,但不能肯定特定行中的更改。
啓用 SQL 緩存
爲了在 SQL Server 7.0 和 SQL Server 2000 中使用 SQL 緩存依賴項,必須先將 SQL Server 配置爲支持緩存依賴項。ASP.NET 提供了一些實用工具,可用於配置 SQL Server 上的 SQL 緩存,其中包括一個名爲 Aspnet_regsql.exe 的工具和 SqlCacheDependencyAdmin 類。有關如何在 SQL Server 上啓用 SQL 緩存依賴項的更多信息,請參見如何:使用緩存鍵依賴項緩存頁輸出。
SQL Server 2005 實現
SQL Server 2005 爲緩存依賴項實現的模型不一樣於 SQL Server 7.0 和 SQL Server 2000 中的緩存依賴項模型。在 SQL Server 2005 中,不須要執行任何特殊的配置步驟來啓用 SQL 緩存依賴項。此外,SQL Server 2005 還實現了一種更改通知模型,能夠向訂閱了通知的應用程序服務器發送通知,而不是依賴早期版本的 SQL Server 中必需的輪詢模型。
SQL Server 2005 緩存依賴項在接收通知的更改類型方面更具靈活性。SQL Server 2005 監控對特定 SQL 命令的結果集的更改。若是數據庫中發生了將修改該命令的結果集的更改,依賴項便會使緩存的項失效。此功能使得 SQL Server 2005 能夠提供行級別的通知。
對用於測試更改的查詢有一些要求。必須提供徹底限定的表名,其中包括全部者名稱(例如 dbo.authors)。總之,SQL 2005 通知支持 Select 查詢和存儲過程,支持多個查詢和嵌套查詢,但不支持聚合操做(例如 COUNT(*))。有關 SQL Server 2005 支持哪些查詢以及通知規則的更多信息,請參見「SQL Books Online」(SQL 聯機叢書)中的主題「Creating a Query for Notification」(建立通知查詢)。
在 ASP.NET 應用程序中配置 SQL 緩存
在對 SQL Server 7.0 或 SQL Server 2000 進行了緩存依賴項配置後,或是在 SQL Server 2005 中建立了適當的命令依賴項後,就能夠配置您的應用程序來使用 SQL 緩存依賴項,如同配置任何其餘緩存依賴項同樣。例如,能夠在 Web.config 文件中建立一個緩存配置文件,而後在應使用 SQL 緩存依賴項的每一個頁中引用該緩存配置文件。還能夠在經過 SqlCacheDependency 類以編程方式啓用 SQL 緩存依賴項後再使用它。有關更多信息,請參見如何:使用緩存鍵依賴項緩存頁輸出。
緩存 ASP.NET 頁
ASP.NET 使您能夠緩存 ASP.NET 頁所生成的部分響應或全部響應,在 ASP.NET 中將這種技術稱爲輸出緩存。能夠在發出請求的瀏覽器、響應請求的 Web 服務器以及請求或響應流中任何其餘具備緩存功能的設備(如代理服務器)上緩存頁。緩存爲您提供了一個強有力的方式來提升 Web 應用程序的性能。緩存功能容許利用緩存知足對頁的後續請求,這樣就不須要再次運行最初建立該頁的代碼。對站點中訪問最頻繁的頁進行緩存能夠充分地提升 Web 服務器的吞吐量(一般以每秒的請求數計算)。
能夠在頁或配置文件中以聲明方式或者經過編程方式使用緩存 API 指定緩存設置。有關更多信息,請參見設置頁的可緩存性。
能夠根據查詢字符串參數值或窗體變量值(控件值)緩存頁。必須經過使用 @ OutputCache 指令的 VaryByParam 屬性,顯式啓用基於這些類型的值的緩存。有關更多信息,請參見緩存頁的多個版本。
當用戶請求某一緩存頁時,ASP.NET 根據已經爲該頁定義的緩存策略肯定其緩存輸出是否仍有效。若是該輸出有效,則將該緩存輸出發送到客戶端,而且不從新處理該頁。ASP.NET 容許您在此驗證檢查期間運行代碼,以即可以編寫用於檢查頁是否有效的自定義邏輯。有關更多信息,請參見如何:檢查緩存頁的有效性。
有時,緩存整個頁是不切實際的,由於在每次請求時可能須要更改頁的某些部分。在這些狀況下,能夠緩存頁的一部分。ASP.NET 提供了只緩存 ASP.NET 頁的幾部分的功能。有關更多信息,請參見緩存 ASP.NET 頁的某些部分。
某頁或用戶控件的可緩存性指某頁可否在其響應生命週期內緩存到某個設備上。這些設備包括髮出請求的客戶端(瀏覽器),響應請求的 Web 服務器,以及請求或響應流中任何具備緩存功能的設備(例如代理服務器)。
若是您在設計時知道某頁須要什麼樣的可緩存性設置,您能夠以聲明方式設置可緩存性。該頁將爲全部請求使用相同的可緩存性設置。有關更多信息,請參見設置頁的可緩存性。
以聲明方式設置頁的可緩存性
-
在頁中包含 @ OutputCache 指令,並定義 Duration 和 VaryByParam 屬性。
-
在 @ OutputCache 指令中包含 Location 屬性,並將其值定義爲 OutputCacheLocation 枚舉中的下列值之一:Any、Client、Downstream、Server、ServerAndClient 或 None。
下面的代碼演示如何將頁的可緩存性設置爲 60 秒:
<%@ OutputCache Duration="60" VaryByParam="None"%>
注意
默認設置爲 Any。若是未定義 Location 屬性,則能夠將頁輸出緩存在與響應有關的全部具備緩存功能的網絡設備上。其中包括請求客戶端、原服務器、以及響應經過的任何代理服務器。
使用緩存配置文件以聲明方式設置頁的可緩存性
-
在應用程序的 Web.config 文件中定義緩存配置文件,在配置文件中包括 duration 和 varyByParam 設置。
下面的 <caching> 配置元素定義名爲 Cache30Seconds 的緩存配置文件,它將在服務器上將頁緩存 30 秒之久。
<caching> <outputCacheSettings> <outputCacheProfiles> <add name="Cache30Seconds" duration="30" varyByParam="none" /> </outputCacheProfiles> </outputCacheSettings> </caching>
-
在使用配置文件的每一個 ASP.NET 頁中包含 @ OutputCache 指令,並將 CacheProfile 屬性設置爲 Web.config 文件中定義的緩存配置文件的名稱。
下面的代碼指定頁應當使用名爲 Cache30Seconds 的緩存配置文件:
<%@ OutputCache CacheProfile="Cache30Seconds" %>
頁或用戶控件的可緩存性指的是某一頁是否能在該頁的響應生命週期內緩存在某個設備上。緩存頁的這些設備包括髮出請求的瀏覽器,響應請求的 Web 服務器,以及請求或響應流中任何可執行緩存的設備,如代理服務器。
若是應用程序將根據運行時條件(如讀取請求標頭)肯定可緩存性,您能夠經過編程方式設置可緩存性。有關更多信息,請參見設置頁的可緩存性。
以編程方式設置頁的可緩存性
-
在頁的代碼中,調用 Response 對象的 Cache 屬性的 SetCacheability 方法。
下面的代碼將 Cache-Control HTTP 標頭設置爲 Public。
C#Response.Cache.SetCacheability(HttpCacheability.Public); Response.Cache.SetCacheability(HttpCacheability.Public)
若是將 NoCache 或 ServerAndNoCache 傳遞到 SetCacheability 方法以防止請求的瀏覽器在它本身的歷史記錄文件夾中緩存某一頁,那麼任什麼時候候當某個用戶單擊「後退」或「前進」按鈕時,都會請求響應的新版本。經過調用 Cache 屬性的 SetAllowResponseInBrowserHistory 方法,而且爲 allow 參數傳遞 true 值,您能夠按條件重寫此行爲。
若是將可緩存性設置爲除 NoCache 或 ServerAndNoCache 以外的任何值,ASP.NET 將忽略由 SetAllowResponseInBrowserHistory 方法設置的值。
若要致使某一頁添加到輸出緩存中,須要爲該頁創建到期策略。這能夠經過以聲明方式或編程方式來實現。
以聲明方式爲頁設置輸出緩存到期時間
-
將 @ OutputCache 指令包括在您要緩存其響應的 ASP.NET 頁(.aspx 文件)中。將 Duration 屬性設置爲一個正數值,將 VaryByParam 屬性設置爲一個值。
注意
默認狀況下,@ OutputCache 指令將 Cache-Control 標頭設置爲 Any。
例如,下面的 @ OutputCache 指令將頁的到期時間設置爲 60 秒:
<%@ OutputCache Duration="60" VaryByParam="None" %>
注意
在使用 @ OutputCache 指令時,必須包括一個 VaryByParam 屬性,不然將出現分析器錯誤。若是不但願使用 VaryByParam 屬性提供的功能,請將它的值設置爲「None」。有關更多信息,請參見緩存頁的多個版本。
以編程方式爲頁設置輸出緩存到期時間
-
在該頁的代碼中,在 Response 對象的 Cache 屬性中設置該頁的到期策略。
注意
若是以編程方式設置頁的到期時間,則您還必須爲緩存的頁設置 Cache-Control 標頭。爲此,請調用 SetCacheability 方法並向其傳遞 HttpCacheability 枚舉值 Public。
下面的代碼示例設置與前面過程當中的 @ OutputCache 指令相同的緩存策略。
C#Response.Cache.SetExpires(DateTime.Now.AddSeconds(60)); Response.Cache.SetCacheability(HttpCacheability.Public); Response.Cache.SetValidUntilExpires(true);
Visual BasicResponse.Cache.SetExpires(DateTime.Now.AddSeconds(60)) Response.Cache.SetCacheability(HttpCacheability.Public) Response.Cache.SetValidUntilExpires(True)
當緩存頁到期時,之後對該頁的請求將致使動態生成的響應。會在指定的持續時間內緩存該響應頁。
用戶請求緩存頁時,ASP.NET 根據您在該頁中定義的緩存策略來肯定緩存輸出是否仍然有效。若是緩存輸出有效,則將輸出發送到客戶端,而且不從新處理該頁。可是,ASP.NET 提供了使用驗證回調在該驗證檢查期間運行代碼的功能,所以您能夠編寫自定義邏輯來檢查該頁是否有效。利用驗證回調,可使在使用緩存依賴項的正常進程以外的緩存頁無效。
以編程方式檢查緩存頁的有效性
-
定義 HttpCacheValidateHandler 類型的事件處理程序,幷包括檢查緩存頁響應的有效性的代碼。
驗證處理程序必須返回下列 HttpValidationStatus 值之一:
-
Invalid 指示緩存頁無效,將從緩存中移除該頁,而且該請求將被做爲緩存未命中處理。
-
IgnoreThisRequest 致使將請求視爲緩存未命中處理。所以,將從新處理該頁,但不會使緩存頁無效。
-
Valid 指示緩存頁有效。
下面的代碼示例闡釋名爲 ValidateCacheOutput 的驗證處理程序,該處理程序肯定查詢字符串變量 status 包含值「invalid」仍是「ignore」。若是狀態值爲「invalid」,則該方法返回 Invalid,而且使該頁在緩存中無效。若是狀態值爲「ignore」,則該方法返回 IgnoreThisRequest,而且該頁仍保留在緩存中,但爲該請求生成一個新響應。
C#public static void ValidateCacheOutput(HttpContext context, Object data, ref HttpValidationStatus status) { if (context.Request.QueryString["Status"] != null) { string pageStatus = context.Request.QueryString["Status"]; if (pageStatus == "invalid") status = HttpValidationStatus.Invalid; else if (pageStatus == "ignore") status = HttpValidationStatus.IgnoreThisRequest; else status = HttpValidationStatus.Valid; } else status = HttpValidationStatus.Valid; }
Visual BasicPublic Shared Sub ValidatePage(ByVal context As HttpContext, _ ByVal data As [Object], ByRef status As HttpValidationStatus) If Not (context.Request.QueryString("Status") Is Nothing) Then Dim pageStatus As String = context.Request.QueryString("Status") If pageStatus = "invalid" Then status = HttpValidationStatus.Invalid ElseIf pageStatus = "ignore" Then status = HttpValidationStatus.IgnoreThisRequest Else status = HttpValidationStatus.Valid End If Else status = HttpValidationStatus.Valid End If End Sub
-
-
從其中一個頁生命週期事件(如頁的 Load 事件)中調用 AddValidationCallback 方法,將您在步驟 1 中定義的事件處理程序做爲第一個參數傳遞。
下面的代碼示例將 ValidateCacheOutput 方法設置爲驗證處理程序。
C#protected void Page_Load(object sender, EventArgs e) { Response.Cache.AddValidationCallback( new HttpCacheValidateHandler(ValidateCacheOutput), null); }
Visual BasicProtected Sub Page_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Me.Load Response.Cache.AddValidationCallback( _ New HttpCacheValidateHandler(AddressOf ValidatePage), Nothing) End Sub
有時緩存整個頁是不現實的,由於頁的某些部分可能在每次請求時都須要更改。在這些狀況下,只能緩存頁的一部分。執行此操做有兩個選項:控件緩存和緩存後替換。
在控件緩存(也稱爲片斷緩存)中,能夠經過建立用戶控件來包含緩存的內容,而後將用戶控件標記爲可緩存來緩存部分頁輸出。該選項容許緩存頁中的特定內容,而在每次都從新建立整個頁。例如,若是建立的頁顯示大量動態內容(如股票信息),但也有某些部分是靜態的(如每週摘要),則能夠在用戶控件中建立這些靜態部分並將用戶控件配置爲緩存。
緩存後替換與控件緩存正好相反。它對頁進行緩存,可是頁中的某些片斷是動態的,所以不會緩存這些片斷。例如,若是建立的頁在設定的時間段內徹底是靜態的(例如新聞報道頁),能夠設置爲緩存整個頁。若是爲緩存的頁添加旋轉廣告橫幅,則在頁請求之間,廣告橫幅不會變化。然而,使用緩存後替換,能夠對頁進行緩存,但能夠將特定部分標記爲不可緩存。在本例中,將廣告橫幅標記爲不可緩存。它們將在每次頁請求時動態建立,並添加到緩存的頁輸出中。有關緩存後替換的更多信息,請參閱動態更新緩存頁的部分。
控件緩存
經過建立用戶控件來緩存內容,能夠將頁上須要花費寶貴的處理器時間來建立的某些部分(例如數據庫查詢)與頁的其餘部分分離開。只需佔用不多服務器資源的部分能夠在每次請求時動態生成。
在標識了要緩存的頁的部分,並建立了用以包含這些部分中的每一個部分的用戶控件後,您必須肯定這些用戶控件的緩存策略。您可使用 @ OutputCache 指令,或者在代碼中使用 PartialCachingAttribute 類,以聲明的方式爲用戶控件設置這些策略。
例如,若是在用戶控件文件(.ascx 文件)的頂部包括下面的指令,則該控件的一個版本將在輸出緩存中存儲 120 秒。
<%@ OutputCache Duration="120" VaryByParam="None" %>
若要在代碼中設置緩存參數,能夠在用戶控件的類聲明中使用一個屬性。例如,若是在類聲明的元數據中包括下面的屬性,則該內容的一個版本將在輸出緩存中存儲 120 秒:
[PartialCaching(120)] public partial class CachedControl : System.Web.UI.UserControl { // Class Code }
<PartialCaching(120)> _ Partial Class CachedControl Inherits System.Web.UI.UserControl ' Class Code End Class
有關可在頁輸出中設置的屬性的更多信息,請參閱 @ OutputCache 主題。有關如何開發用戶控件的更多信息,請參見 ASP.NET Web 服務器控件概述。
![]() |
---|
因爲可在頁上嵌套用戶控件,您還能夠嵌套已放置到輸出緩存中的用戶控件。能夠爲頁和嵌套的用戶控件指定不一樣的緩存設置。 |
以編程方式引用緩存的用戶控件
在以聲明的方式建立可緩存的用戶控件時,能夠包括一個 ID 屬性,以便以編程方式引用該用戶控件實例。可是,在代碼中引用用戶控件以前,必須驗證在輸出緩存中是否存在該用戶控件。緩存的用戶控件只在首次請求時動態生成;在指定的時間到期以前,從輸出緩存知足全部的後續請求。肯定用戶控件已實例化後,能夠從包含頁以編程方式操做該用戶控件。例如,若是經過聲明方式將 SampleUserControl 的 ID 分配給用戶控件,則可使用下面的代碼檢查它是否存在。
protected void Page_Load(object sender, EventArgs e) { if (SampleUserControl != null) // Place code manipulating SampleUserControl here. }
Protected Sub Page_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Me.Load If SampleUserControl <> Nothing Then ' Place code manipulating SampleUserControl here. End If End Sub
以不一樣的持續時間緩存頁和用戶控件
能夠爲頁和頁上的用戶控件設置不一樣的輸出緩存持續時間值。若是頁的輸出緩存持續時間長於用戶控件的輸出緩存持續時間,則頁的輸出緩存持續時間優先。例如,若是頁的輸出緩存設置爲 100 秒,而用戶控件的輸出緩存設置爲 50 秒,則包括用戶控件在內的整個頁將在輸出緩存中存儲 100 秒,而與用戶控件較短的時間設置無關。
下面的代碼示例演示了當頁的緩存持續時間長於用戶控件的緩存持續時間時的效果。該頁配置爲緩存 100 秒。
<%@ Page language="C#" %> <%@ Register tagprefix="SampleControl" tagname="Time" src="uc01.ascx" %> <%@ OutputCache duration="100" varybyparam="none" %> <SampleControl:Time runat="server" /><br /> <br /> <br /> This page was most recently generated at:<p> <% DateTime t = DateTime.Now.ToString(); Response.Write(t); %>
<%@ Page language="VB" %> <%@ Register tagprefix="SampleControl" tagname="Time" src="uc01.ascx" %> <%@ OutputCache duration="100" varybyparam="none" %> <SampleControl:Time runat="server" /><br /> <br /> <br /> This page was most recently generated at:<p> <% Dim t As DateTime = DateTime.Now.ToString() Response.Write(t) %>
下面的代碼示例演示了包括在頁中的用戶控件。控件的緩存持續時間設置爲 50 秒。
<% @Control language="C#" %> <% @OutputCache duration="50" varybyparam="none" %> This user control was most recently generated at:<p> <% DateTime t = DateTime.Now.ToString(); Response.Write(t); %>
<% @Control language="VB" %> <% @OutputCache duration="50" varybyparam="none" %> This user control was most recently generated at:<p> <% Dim t As DateTime = DateTime.Now.ToString() Response.Write(t) %>
不過,若是頁的輸出緩存持續時間比用戶控件的輸出緩存持續時間短,則即便已爲某個請求從新生成該頁的其他部分,也將一直緩存用戶控件直到其持續時間到期爲止。例如,若是頁的輸出緩存設置爲 50 秒,而用戶控件的輸出緩存設置爲 100 秒,則頁的其他部分每到期兩次,用戶控件纔到期一次。
下面的代碼演示了一個頁的標記,該頁中包含的用戶控件的緩存持續時間長於該頁的緩存持續時間。該頁配置爲緩存 50 秒。
<%@ Page language="C#" %> <%@ Register tagprefix="SampleControl" tagname="Time" src="uc2.ascx" %> <%@ OutputCache duration="50" varybyparam="none" %> <SampleControl:Time runat="server" /><br /> <br /> <br /> This page was most recently generated at:<p> <% DateTime t = DateTime.Now.ToString(); Response.Write(t); %>
<%@ Page language="VB" %> <%@ Register tagprefix="SampleControl" tagname="Time" src="Uc2.ascx" %> <%@ OutputCache duration="50" varybyparam="none" %> <SampleControl:Time runat="server" /><br /> <br /> <br /> This page was most recently generated at:<p> <% Dim t As DateTime = DateTime.Now.ToString() Response.Write(t) %>
下面的代碼演示了包括在頁中的用戶控件。控件的緩存持續時間設置爲 100 秒。
<% @Control language="C#" %> <% @OutputCache duration="100" varybyparam="none" %> This user control was most recently generated at:<p> <% DateTime t = DateTime.Now.ToString(); Response.Write(t); %>
<% @Control language="VB" %> <% @OutputCache duration="100" varybyparam="none" %> This user control was most recently generated at:<p> <% Dim t As DateTime = DateTime.Now.ToString() Response.Write(t) %>
有時,您可能但願緩存某頁,可是會基於請求爲該頁建立不一樣的版本。例如,根據查詢字符串中傳遞的值,該頁可能具備不一樣的輸出。
ASP.NET 容許在輸出緩存中緩存同一頁的多個版本。輸出緩存可能會因下列因素而異:
-
初始請求 (HTTP GET) 中的查詢字符串。
-
回發時傳遞的控制值(HTTP POST 值)。
-
隨請求傳遞的 HTTP 標頭。
-
發出請求的瀏覽器的主版本號。
-
該頁中的自定義字符串。在這種狀況下,能夠在 Global.asax 文件中建立自定義代碼以指定該頁的緩存行爲。
能夠經過如下兩種方法來緩存頁輸出的多個版本:使用 @ OutputCache 指令的屬性以聲明方式,或者使用 HttpCachePolicy 類的屬性和方法以編程方式。
@ OutputCache 指令包括四個可用來緩存頁輸出的多個版本的屬性:
-
VaryByParam 屬性可用來使緩存輸出因查詢字符串而異。
-
VaryByControl 屬性可用來使緩存輸出因控制值而異。
-
VaryByHeader 屬性可用來使緩存輸出因請求的 HTTP 標頭而異。
-
VaryByCustom 屬性可用來使緩存輸出因瀏覽器類型或您定義的自定義字符串而異。
注意
您必須在任何 @ OutputCache 指令中包括 VaryByParam 屬性或 VaryByControl 屬性。可是,若是您不須要使緩存輸出因控制值或參數而異,則能夠定義值爲 None 的 VaryByParam。
HttpCachePolicy 類提供兩個屬性和一個方法,您能夠經過它們以編程方式指定與以聲明方式所能設置的緩存配置相同的緩存配置。使用 VaryByParams 和 VaryByHeaders 屬性能夠分別指定查詢字符串參數和標頭名稱做爲緩存策略改變依據。使用 SetVaryByCustom 方法能夠定義要做爲輸出緩存改變依據的自定義字符串。
有時,當緩存中的某一項被移除時,您可能須要從輸出緩存中移除一頁。例如,您可能使用一頁來顯示放置在應用程序緩存中並供多個頁使用的佔用大量進程的報告。當該報告已更改或已從緩存中移除時,您但願將頁輸出也從緩存中移除,由於該報告再也不有效。爲此,可以使緩存的頁輸出依賴於其餘緩存項。
![]() |
---|
經過調用 RemoveOutputCacheItem 方法,可顯式移除輸出緩存中的任何頁。能夠從 Global.asax 文件、自定義 ASP.NET 服務器控件或頁中執行此操做,具體取決於應用程序的須要。 |
使緩存的頁輸出依賴於另外一緩存項
-
在頁中,以聲明方式或編程方式指定緩存設置。有關更多信息,請參見如何:設置 ASP.NET 頁緩存的過時時間值、設置頁的可緩存性和緩存頁的多個版本。
-
在頁代碼中調用 AddCacheItemDependency 方法。將建立依賴項的緩存項的名稱做爲 cacheKey 參數傳遞。
下面的代碼示例演示如何在名爲 ProcessIntensiveReport 的項上設置依賴項。當此項被修改或移除時,將從緩存中移除頁輸出。
C#protected void Page_Load(object sender, EventArgs e) { Response.AddCacheItemDependency("ProcessIntensiveReport"); // Set additional properties to enable caching. Response.Cache.SetExpires(DateTime.Now.AddSeconds(60)); Response.Cache.SetCacheability(HttpCacheability.Public); Response.Cache.SetValidUntilExpires(true); }
Visual BasicProtected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load Response.AddCacheItemDependency("ProcessIntensiveReport") ' Set additional properties to enable caching. Response.Cache.SetExpires(DateTime.Now.AddSeconds(60)) Response.Cache.SetCacheability(HttpCacheability.Public) Response.Cache.SetValidUntilExpires(True) End Sub
注意
不能在 ASP.NET 用戶控件中調用 AddCacheItemDependency 方法。不過,在指定 @ OutputCache 指令的任何用戶控件中,均可以建立描述緩存鍵依賴項的 CacheDependency 對象,並將其分配給 UserControl 對象的 Dependency 屬性。
-
有時候,您可能須要在文件發生更改時從輸出緩存中移除某一頁。例如,您可能有這樣一頁:該頁從生成 XML 文件做爲輸出且佔用大量進程的報告中獲取其內容。僅當 XML 文件發生更改時,才須要從新處理該頁。要將從新處理限制爲僅在須要的時候進行,可使頁的緩存策略依賴於單個文件。若有必要,可使緩存頁依賴於多個文件。
![]() |
---|
經過調用 RemoveOutputCacheItem 方法,可顯式移除輸出緩存中的任何頁。能夠從 Global.asax 文件、自定義 ASP.NET 服務器控件或頁中執行此操做,具體取決於應用程序的須要。 |
使緩存頁輸出依賴於一個文件
-
以聲明方式或編程方式指定緩存頁輸出的設置。有關更多信息,請參見如何:設置 ASP.NET 頁緩存的過時時間值、設置頁的可緩存性和緩存頁的多個版本。
-
在頁代碼中調用 AddFileDependency 方法。將建立依賴項的文件的路徑做爲方法的 filename 參數傳遞。
下面的代碼示例在 TextFile1.txt 文件上設置一個文件依賴項。當文件發生更改時,將從緩存中移除頁輸出。
C#protected void Page_Load(object sender, EventArgs e) { string fileDependencyPath = Server.MapPath("TextFile1.txt"); Response.AddFileDependency(fileDependencyPath); // Set additional properties to enable caching. Response.Cache.SetExpires(DateTime.Now.AddSeconds(60)); Response.Cache.SetCacheability(HttpCacheability.Public); Response.Cache.SetValidUntilExpires(true); }
Visual BasicProtected Sub Page_Load(ByVal sender As Object, _ ByVal e As EventArgs) Handles Me.Load Dim fileDependencyPath As String = _ Server.MapPath("TextFile1.txt") Response.AddFileDependency(fileDependencyPath) ' Set additional properties to enable caching. Response.Cache.SetExpires(DateTime.Now.AddSeconds(60)) Response.Cache.SetCacheability(HttpCacheability.Public) Response.Cache.SetValidUntilExpires(True) End Sub
注意
不能從 ASP.NET 用戶控件使用這些方法。可是,在指定 @ OutputCache 指令的任何用戶控件中,您均可以建立一個文件依賴項,並將其分配給 Dependency 屬性。
使緩存頁輸出依賴於文件組
-
以聲明方式或編程方式指定緩存頁輸出的設置。有關更多信息,請參見如何:設置 ASP.NET 頁緩存的過時時間值、設置頁的可緩存性和緩存頁的多個版本。
-
調用 AddFileDependencies 方法,並將數組做爲 filenames 參數傳遞。
下面的代碼示例建立包含 TextFile1.txt 和 XMLFile1.xml 文件的文件路徑的字符串數組,並使頁輸出依賴於這兩個文件。若是修改了其中任何一個文件,將從緩存中移除頁輸出。
C#protected void Page_Load(object sender, EventArgs e) { string[] fileDependencies; string fileDependency1 = Server.MapPath("TextFile1.txt"); string fileDependency2 = Server.MapPath("XMLFile1.xml"); fileDependencies = new String[] { fileDependency1, fileDependency2 }; Response.AddFileDependencies(fileDependencies); }
Visual BasicProtected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load Dim fileDependencies() As String Dim fileDependency1 As String = Server.MapPath("TextFile1.txt") Dim fileDependency2 As String = Server.MapPath("XMLFile1.xml") fileDependencies = New String() {fileDependency1, _ fileDependency2} Response.AddFileDependencies(fileDependencies) End Sub
Public