Cache有多種翻譯,能夠是高速緩衝存儲器,也能夠是法國的服裝品牌,本文只是簡單的談談就是ASP.NET 中Cache,作過Web應用程序的都知道,若是網站訪問量比較大,系統應用程序能夠將那些頻繁訪問的數據,以及那些須要大量處理時間來建立的數據存儲在內存中,從而提升性能。 舉一個很簡單的例子,若是在博客園發佈文章到首頁,發佈以後是不能即時看到本身的文章的,大概一分鐘以後才能刷出數據,這就是經常使用的頁面緩存.緩存分爲兩種,通常都是頁面緩存以及應用程序緩存。html
頁面輸出緩存是一類針服務器應用程序的典型緩存。 利用輸出緩存,能夠存儲呈現的 HTML。 提供存儲的 HTML 以響應相同頁的後續請求。 可以使用輸出緩存來緩存整個網頁或僅緩存 ASP.NET 控件的輸出。頁輸出緩存在內存中存儲處理後的 ASP.NET 頁的內容。 這可以讓 ASP.NET 向客戶端發送頁響應,而沒必要再次通過頁處理生命週期。 頁輸出緩存對於那些不常常更改,但須要大量處理才能建立的頁特別有用。 例如,若是建立大通訊量的網頁來顯示不須要頻繁更新的數據,頁輸出緩存則能夠極大地提升該頁的性能。 能夠分別爲每一個頁配置頁緩存,也能夠在 Web.config 文件中建立緩存配置文件。利用緩存配置文件,只定義一次緩存設置就能夠在多個頁中使用這些設置。前端
首先看一個經常使用的,用來控制頁面或者用戶控制輸出的持續輸出30s時間,WebForm只須要在aspx頁面寫個OutPutCache:web
<%@ OutputCache Duration="30" VaryByParam="None" %>
asp.net mvc頁面生命週期跟WebForm那一套不同,這個時候就須要在Action動手改改:數據庫
[OutputCache(Duration = 30,VaryByParam="none")] public ActionResult CacheTest() { return View(); }
頁面緩存的實現和處理方式有不少種,先從OutPutCache中的各類特性的,每種特性,對應着不一樣的實現方式:編程
<%@ OutputCache Duration="100"(必填) Location="Any | Client | Downstream | Server | None | ServerAndClient " Shared="True | False" VaryByControl="控件名稱" VaryByCustom="Test" VaryByHeader="headers" VaryByParam="parametername" VaryByContentEncoding="encodings" CacheProfile="cache profile name | ''" NoStore="true | false" SqlDependency="database/table name pair | CommandNotification" ProviderName="Provider Name" %>
OutPutCache上面的設置很簡單,Duration是必填的,頁或用戶控件進行緩存的時間(秒),Location是指定緩存的位置,由枚舉OutputCacheLocation來肯定,包含在用戶控件(.ascx 文件)中的 @ OutputCache 指令不支持此特性。數組
VaryByControl一個分號分隔的字符串列表,用於更改用戶控件的輸出緩存。 這些字符串表明用戶控件中聲明的 ASP.NET 服務器控件的 ID 屬性值,在 ASP.NET 頁和用戶控件上使用 @ OutputCache 指令時,須要此特性或 VaryByParam 特性,有的時候咱們緩存整個頁面確定不是太現實的,不少狀況下只是緩存一部分頁面,新建一個用戶控件:瀏覽器
1 <%@ Control Language="C#" AutoEventWireup="true" CodeBehind="Test.ascx.cs" Inherits="MyWebForm.Test" %> 2 <%@ OutputCache Duration="5" VaryByParam="None" %> 3 <% string t = DateTime.Now.ToString(); 4 Response.Write(t); %>
在aspx頁面中使用用戶控件:緩存
1 <%@ Register Src="~/Test.ascx" TagPrefix="uc1" TagName="Test" %> 2 <%@ OutputCache Duration="10" VaryByParam="None" %> 3 <uc1:Test runat="server" ID="Test1" />
這裏面涉及到一個問題,就是頁面設置的時間和控件設置的時間,頁面是10s,控件是5s,控件與頁面都是10s刷一次,以頁面時間爲主;若是頁面是10s,控件是20s,那麼頁面10s刷一次,控件20s刷一次,簡單點理解就是控件以時間長的爲主;服務器
asp.net mvc 中ascx全部的功能就是View頁面,跟局部視圖調用同樣,新建一個Test.ascx,經過控制器去訪問:mvc
1 <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %> 2 <% string t = DateTime.Now.ToString(); Response.Write(t); %>
1 [OutputCache(Duration=5,VaryByParam="none")] 2 public ActionResult Test() 3 { 4 Response.Cache.SetOmitVaryStar(true); 5 return View(); 6 }
注意:控制器多加了Response.Cache.SetOmitVaryStar(true),這個Bug還比較隱蔽,詳情可參考:
http://www.cnblogs.com/dudu/archive/2012/08/27/asp_net_mvc_outputcache.html
VaryByCustom表示自定義輸出緩存要求的任意文本。 若是特性的賦值爲 browser,緩存將隨瀏覽器名稱和主要版本信息的不一樣而異。 若是輸入自定義字符串,則必須在應用程序的 Global.asax 文件中重寫 GetVaryByCustomString方法, 根據用戶的主機名或者瀏覽器起版本給出緩存,不存在的話就須要新建緩存,若是存在話就不須要新建緩存。
public override string GetVaryByCustomString(HttpContext context, string arg) { if (arg == "Test") { return "瀏覽器版本=" + context.Request.Browser.MinorVersion.ToString(); //return "用戶主機=" + // context.Request.UserHostName; } return base.GetVaryByCustomString(context, arg); }
VaryByHeader
分號分隔的 HTTP 標頭列表,用於使輸出緩存發生變化。 將該特性設爲多標頭時,對於每一個指定標頭組合,輸出緩存都包含一個不一樣版本的請求文檔。設置 VaryByHeader 特性將啓用在全部 HTTP 1.1 版緩存中緩存項,而不只僅在 ASP.NET 緩存中進行緩存。 用戶控件中的 @ OutputCache指令不支持此特性。
VaryByParam
分號分隔的字符串列表,用於使輸出緩存發生變化。 默認狀況下,這些字符串對應於使用 GET 方法特性發送的查詢字符串值,或者使用 POST 方法發送的參數。 將該特性設置爲多個參數時,對於每一個指定參數組合,輸出緩存都包含一個不一樣版本的請求文檔。 可能的值包括 none、星號 (*) 以及任何有效的查詢字符串或 POST 參數名稱。
頁面經過URL連接訪問,要緩存頁面,百分之九十的狀況的下頁面是會有參數傳遞的,若是你設置爲none,那麼你用get或者post請求的時候是不會緩存的,設爲*是最簡單的什麼都不用管,若是你只想查name的時候緩存一下,那麼你直接設置一下就行.
[OutputCache(Duration = 30,VaryByParam="name")] public ActionResult CacheTest(string name) { if (name=="1") { ViewData["Test"] = "測試"; } return View(); }
CacheProfile
配置文件中設置緩存。 這是可選特性,默認值爲空字符串 ("")。包含在用戶控件(.ascx 文件)中的 @ OutputCache 指令不支持此特性。 在頁中指定此屬性時,屬性值必須與 outputCacheSettings 節下面的 outputCacheProfiles 元素中的一個可用項的名稱匹配。 若是此名稱與配置文件項不匹配,將引起異常。
[OutputCache(CacheProfile = "myProfile",VaryByParam="none")] public ActionResult Test() { Response.Cache.SetOmitVaryStar(true); return View(); }
<system.web> <caching> <outputCacheSettings> <outputCacheProfiles> <add name="myProfile" duration="10"/> </outputCacheProfiles> </outputCacheSettings> </caching> </system.web>
Shared一個布爾值,肯定用戶控件輸出是否能夠由多個頁共享。 默認值爲 false,包含在 ASP.NET 頁(.aspx 文件)中的 @ OutputCache 指令不支持此特性。
NoStore一個布爾值,它決定了是否阻止敏感信息的二級存儲。在用戶控件(ascx)中使用的時候須要注意加上Response.Cache.SetNoStore();
SqlDependency標識一組數據庫/表名稱對的字符串值,頁或控件的輸出緩存依賴於這些名稱對。
ProviderName 一個字符串值,標識要使用的自定義輸出緩存提供程序。
VaryByContentEncodings 以分號分隔的字符串列表,用於更改輸出緩存。
應用程序緩存提供了一種編程方式,可經過鍵/值對將任意數據存儲在內存中。 使用應用程序緩存與使用應用程序狀態相似。 可是,與應用程序狀態不一樣的是,應用程序緩存中的數據是易失的, 即數據並非在整個應用程序生命週期中都存儲在內存中。 使用應用程序緩存的優勢是由 ASP.NET 管理緩存,它會在項過時、無效、或內存不足時移除緩存中的項。 還能夠配置應用程序緩存,以便在移除項時通知應用程序。使用應用程序緩存的模式是,肯定在訪問某一項時該項是否存在於緩存中,若是存在,則使用。 若是該項不存在,則能夠從新建立該項,而後將其放回緩存中。 這一模式可確保緩存中始終有最新的數據。
經過鍵和值直接設置項向緩存賦值
List<Person> list = new List<Person>(){new Person(){Name="Small",Age=24}, new Person(){Name="Fly",Age=24}, new Person(){Name="Elephant",Age=24}}; Cache["Test"] = list;
Insert的方式
Cache.Insert("Fly", "緩存2");
添加依賴項,能夠是其餘已存在的緩存,也能夠是已存在的文件:
Cache.Insert("Fly", "緩存2"); Cache.Insert("Elephant", "緩存3",new CacheDependency(null, new string[]{"Fly"}));//key爲Elephant, value爲緩存3,依賴於key爲Fly的緩存
Cache.Insert("Elephant", "緩存3",new CacheDependency(Server.MapPath("路徑")));
插入多個緩存依賴
CacheDependency dep1 = new CacheDependency(null, new string[] { "Fly" }); CacheDependency dep2 = new CacheDependency(Server.MapPath("路徑")); AggregateCacheDependency cacheList = new AggregateCacheDependency(); cacheList.Add(dep1); cacheList.Add(dep2); Cache.Insert("Elephant", "緩存3",cacheList);
絕對過時和滑動過時這個兩個名字比較有意,絕對過時枚舉英文是NoSlidingExpiration(不滑動),滑動過時NoAbsoluteExpiration(不絕對),這裏面還設置了CacheItemPriority,這枚舉你們本身看下就行,還有一個自動刪除,緩存到期後執行刪除方法:
//絕對過時時間的時間爲30s,過完30s以後就沒有緩存 Cache.Insert("Tiger", "老虎",null, DateTime.Now.AddSeconds(30), Cache.NoSlidingExpiration,CacheItemPriority.High,Show); //滑動過時時間的時間爲1分鐘,只要一直刷新一直有,若是刷新間隔超過一分鐘的緩存就沒啦 Cache.Insert("Dragon", "龍", null, Cache.NoAbsoluteExpiration,new TimeSpan(0, 0, 60)); public void Show(string key, object value, CacheItemRemovedReason call) { if (key=="Pig") { Cache.Remove("Pig"); } }
Add的形式(該方法沒有重載)
Cache.Add("Cow", "牛", null, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.Default, null);
ASP.NET 1到3.5中的輸出緩存有一個限制,就是緩存存儲自己不是可擴展的,ASP.NET 4.0以後是支持緩存擴展的。 經過緩存的擴展,能夠保存HTML頁面或者內存中的數據, 這些存儲選項包括本地或遠程磁盤、雲存儲和分佈式緩存引擎。ASP.NET 中的輸出緩存提供程序擴展性,能夠爲網站設計更好的輸出緩存策略。 例如,能夠建立這樣一個輸出緩存提供程序,該程序在內存中緩存站點流量排名靠前的頁面,而在磁盤上緩存流量較低的頁面,也能夠對所呈現頁面的各類變化因素組合進行緩存,但應使用分佈式緩存以減小前端 Web 服務器的內存消耗。實現可擴展,須要建立一個繼承自 OutputCacheProvider 的類:
public class MyCacheProvide : OutputCacheProvider { public override object Add(string key, object entry, DateTime utcExpiry) { throw new NotImplementedException(); } public override object Get(string key) { throw new NotImplementedException(); } public override void Remove(string key) { throw new NotImplementedException(); } public override void Set(string key, object entry, DateTime utcExpiry) { throw new NotImplementedException(); } }
而後配置文件中進行相應配置:
<caching> <outputCache defaultProvider="AspNetInternalProvider"> <providers> <add name="DiskCache" type="MyWeb.Controllers.MyCacheProvide, MyWeb" /> </providers> </outputCache> </caching>
默認狀況下,全部 HTTP 響應、所呈現的頁面和控件(其中 defaultProvider 特性設置爲 AspNetInternalProvider)所示的內存輸出緩存。經過爲 defaultProvider 指定不一樣的提供程序名稱,能夠更改用於 Web 應用程序的默認輸出緩存提供程序。默認值爲「AspNetInternalProvider", 這是 ASP.NET 提供的內存緩存。