ASP.NET與ASP.NET MVC 中Cache的總結


Cache有多種翻譯,可以是高速緩沖存儲器,也可以是法國的服裝品牌,本文只是簡單的談談就是ASP.NET 中Cache,做過Web應用程序的都知道,如果網站訪問量比較大,系統應用程序可以將那些頻繁訪問的數據,以及那些需要大量處理時間來創建的數據存儲在內存中,從而提高性能。 舉一個很簡單的例子,如果在博客園發布文章到首頁,發布之后是不能即時看到自己的文章的,大概一分鍾之后才能刷出數據,這就是常用的頁面緩存.緩存分為兩種,一般都是頁面緩存以及應用程序緩存。

頁面緩存

頁面輸出緩存是一類針服務器應用程序的典型緩存。 利用輸出緩存,可以存儲呈現的 HTML。 提供存儲的 HTML 以響應相同頁的后續請求。 可使用輸出緩存來緩存整個網頁或僅緩存 ASP.NET 控件的輸出。頁輸出緩存在內存中存儲處理后的 ASP.NET 頁的內容。 這可讓 ASP.NET 向客戶端發送頁響應,而不必再次經過頁處理生命周期。 頁輸出緩存對於那些不經常更改,但需要大量處理才能創建的頁特別有用。 例如,如果創建大通信量的網頁來顯示不需要頻繁更新的數據,頁輸出緩存則可以極大地提高該頁的性能。 可以分別為每個頁配置頁緩存,也可以在 Web.config 文件中創建緩存配置文件。利用緩存配置文件,只定義一次緩存設置就可以在多個頁中使用這些設置。

首先看一個常用的,用來控制頁面或者用戶控制輸出的持續輸出30s時間,WebForm只需要在aspx頁面寫個OutPutCache:

<%@ 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,通過控制器去訪問:

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();
        }
    }
View Code

然后配置文件中進行相應配置:

  <caching>
      <outputCache defaultProvider="AspNetInternalProvider">
        <providers>
          <add name="DiskCache" type="MyWeb.Controllers.MyCacheProvide, MyWeb" />
        </providers>
      </outputCache>
    </caching>

默認情況下,所有 HTTP 響應、所呈現的頁面和控件(其中 defaultProvider 特性設置為 AspNetInternalProvider)所示的內存輸出緩存。通過為 defaultProvider 指定不同的提供程序名稱,可以更改用於 Web 應用程序的默認輸出緩存提供程序。默認值為“AspNetInternalProvider", 這是 ASP.NET 提供的內存緩存。 


免責聲明!

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



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