系統緩存全解析3:頁面局部緩存

系統緩存全解析3:頁面局部緩存

有時緩存整個頁面是不現實的,由於頁的某些部分可能在每次請求時都須要變化。在這些狀況下,只能緩存頁的一部分。顧名思義,頁面部分緩存是將頁面部份內容保存在內存中以便響應用戶請求,而頁面其餘部份內容則爲動態內容。頁面部分緩存的實現包括兩種方式:控件緩存和替換後緩存html

 

1. 控件緩存(也稱爲片斷緩存)數據庫

    這種方式容許將須要緩存的信息包含在一個用戶控件內,而後,將該用戶控件標記爲可緩存的,以此來緩存頁面輸出的部份內容。該選項容許緩存頁面中的特定內 容,而沒有緩存整個頁面,所以,每次都需從新建立整個頁。例如,若是要建立一個顯示大量動態內容(如股市信息)的頁,其中有些部分爲靜態內容(如每週總 結),這時能夠將靜態部分放在用戶控件中,並容許緩存這些內容。編程

    在ASP.NET中,提供了UserControl這種用戶控件的功能。一個頁面能夠經過多個UserControl來組成。只須要在某個或某幾個UserControl裏設置緩存。緩存

    例如:安全

   那麼能夠在WebUserControl1.ascx的頁頭代碼中添加聲明語句:性能

<%@Control Language="C#"AutoEventWireup="true"CodeBehind="WebUserControl1.ascx.cs"Inherits="CacheWebApp._16_4_5.WebUserControl1"%>spa

<%@ OutputCache Duration="60"VaryByParam="none" %>線程

 

<%=DateTime.Now%>  orm

 

 

 

    調用該控件的頁面WebForm1.aspx代碼:server

<%@Page Language="C#"AutoEventWireup="true"CodeBehind="WebForm1.aspx.cs"Inherits="CacheWebApp._16_4_5.WebForm1"%>

<%@Register src="WebUserControl1.ascx"tagname="WebUserControl1"tagprefix="uc1" %>

<htmlxmlns="http://www.w3.org/1999/xhtml">

<headrunat="server">

    <title>控件緩存</title>

</head>

<body>

    <formid="form1" runat="server">

    <div>

    頁面的:<%=DateTime.Now%>    

    </div>

    <div>

    控件的:<uc1:WebUserControl1ID="WebUserControl11"runat="server" />

    </div>

    </form>

</body>

 

</html>

    這時候刷新WebForm1.aspx頁面時,頁面的時間每次刷新都變化,而用戶控件中的時間數據倒是60秒才變化一次,說明對頁面的「局部」控件實現了緩存,而整個頁面不受影響。

 

2. 緩存後替換

     與控件緩存正好相反。它對整個頁面進行緩存,可是頁中的某些片斷是動態的,所以不會緩存這些片斷。ASP.NET頁面中既包含靜態內容,又包含基於數據庫 數據的動態內容。靜態內容一般不會發生變化。所以,對靜態內容實現數據緩存是很是必要的。然而,那些基於數據的動態內容,則不一樣。數據庫中的數據可能每時 每刻都發生變化,所以,若是對動態內容也實現緩存,可能形成數據不能及時更新的問題。對此問題若是使用前文所述的控件緩存方法,顯然不切實際,並且實現起 來很繁瑣,易於發生錯誤。

     如何實現緩存頁面的大部份內容,而不緩存頁面中的局部某些片斷。ASP.NET 2.0提供了緩存後替換功能。實現該項功能可經過如下三種方法:

    一是以聲明方式使用Substitution控件,

    二是以編程方式使用Substitution控件API,

    三是以隱式方式使用控件。

    前兩種方法的核心是Substitution控件,本節將重點介紹該控件,第三種方法僅專一於控件內置支持的緩存後替換功能,本節僅作簡要說明。

 

(1) Substitution控件應用

     爲提升應用程序性能,可能會緩存整個ASP.NET頁面,同時,可能須要根據每一個請求來更新頁面上特定的部分。例如,可能要緩存頁面的很大一部分,須要動 態更新該頁上與時間或者用戶高度相關的信息。在這種狀況下,推薦使用Substitution控件。Substitution控件可以指定頁面輸出緩存中 須要以動態內容替換該控件的部分,即容許對整頁面進行輸出緩存,而後,使用Substitution控件指定頁中免於緩存的部分。須要緩存的區域只執行一次,而後從緩存讀取,直至該緩存項到期或被清除。動態區域,也就是Substitution控件指定的部分,在每次請求頁面時都執行。Substitution控件提供了一種緩存部分頁面的簡化解決方案。

<%@Page Language="C#"AutoEventWireup="true"CodeBehind="WebForm2.aspx.cs"Inherits="CacheWebApp._16_4_5.WebForm2"%>

<%@ OutputCache Duration="60"VaryByParam="none" %>

<htmlxmlns="http://www.w3.org/1999/xhtml">

<headrunat="server">

    <title>緩存後替換示例</title>

</head>

<body>

    <formid="form1" runat="server">

    <div>

    頁面緩存的時間:<%=DateTime.Now.ToString() %>  

    </div>

    <div>   

       真實(替換)的時間:<asp:SubstitutionID="Substitution1"runat="server" MethodName="getCurrentTime" />

    </div>

    </form>

</body>

 

</html>

 

    頁面後臺代碼:

public partialclass WebForm2 : System.Web.UI.Page

{

    public static string getCurrentTime(HttpContext context)

    {

        return DateTime.Now.ToString();

    }

}

    如上代碼所示,Substitution控件有一個重要屬性:MethodName。該屬性用於獲取或者設置當Substitution控件執行時爲回調而調用的方法名稱。該方法比較特殊,必須符合如下3條標準:

Ø  此方法必須被定義爲靜態方法;

Ø  此方法必須接受HttpContext類型的參數;

Ø  此方法必須返回String類型的值。

 

     在運行狀況下,Substitution控件將自動調用MethodName屬性所定義的方法。該方法返回的字符串即爲要在頁面中的Substitution控件的位置上顯示的內容。 若是頁面設置了緩存所有輸出,那麼在第一次請求時,該頁將運行並緩存其輸出。對於後續的請求,將經過緩存來完成,該頁上的其餘代碼不會再運行。但 Substitution控件及其有關方法則在每次請求時都執行,而且自動更新該控件所表示的動態內容,這樣就實現了總體緩存,局部變化的替換效果。

 

     如上代碼所示,在代碼頭部經過@ OutputCache指令設置頁面輸出緩存過時時間爲5秒,這意味着整個頁面數據都應用了緩存功能。所以,「頁面緩存的時間」所顯示的時間值來自於數據 緩存。這個時間值不會隨着刷新頁面而變化,僅當緩存過時時纔會發生更新。Substitution控件的MethodName屬性值爲 getCurrentTime。該控件顯示的內容來自於getCurrentTime方法的返回值。尤其重要的是,雖然頁面設置了輸出緩存功能,可是每當 頁面刷新時,ASP.NET執行引擎仍然要從新執行Substitution控件,並將MethodName屬性值指定的方法返回值顯示在頁面上,所以, 顯示的是當前最新時間。

示例效果,如圖15-2所示:

圖15-2  緩存後替換

隨着頁面的刷新,真實時間在變,而頁面緩存的時間在指定的緩存時間內始終不變。

 

 

注意:

l  Substitution控件沒法訪問頁上的其餘控件,也就是說,沒法檢查或更改其餘控件的值。可是,代碼確實可使用傳遞給它的參數來訪問當前頁上下文。

l  在緩存頁包含的用戶控件中能夠包含Substitution控件。可是,在輸出緩存用戶控件中不能放置Substitution控件。

l  Substitution控件不會呈現任何標記,其位置所顯示內容徹底取決於所定義方法的返回字符串。

 

(2) Substitution控件API應用

上一小節介紹了以聲明方式使用Substitution控件實現緩存後替換的應用。本節說明另外一種實現方法。該方法的核心是以編程方式利用Substitution控件API實現緩存後替換,相對於以聲明方式使用Substitution控件的方法具備更強靈活性。

經過爲Substitution指定回調方法,實現和聲明一樣的效果。Substitution的回調方法必須是

HttpResponseSubstitutionCallback委託定義的方法,它有兩個特徵:

l  一是返回值必須是String,

l  二是參數有且僅有一個,而且是HttpContext類型。

當須要以編程方式,爲緩存的輸出響應動態生成指定的響應區域時,能夠在頁面代碼中將某個方法(即回調方法)的名稱做爲參 數(HttpResponseSubstitutionCallback)傳遞給Substitution。這樣Substitution就可以使用回調 方法,並將回調方法的返回值做爲給定位置的替代內容顯示出來。

須要注意的是,回調方法必須是線程安全的,能夠是做爲容器的頁面或者用戶控件中的靜態方法,也能夠是其餘任意對象上的靜態方法或實例方法。

 

下面演示一個以編程方式將Substitution 控件添加到輸出緩存網頁。與(1)Substitution控件應用所示的示例完成一樣功能。不一樣的是實現方式。

 

<%@Page Language="C#"AutoEventWireup="true"CodeBehind="WebForm3.aspx.cs"Inherits="CacheWebApp._16_4_5.WebForm3"%>

<%@ OutputCache Duration="60"VaryByParam="none" %>

<htmlxmlns="http://www.w3.org/1999/xhtml">

<headrunat="server">

    <title>緩存後替換-Substitution控件API應用</title>

</head>

<body>

    <formid="form1" runat="server">

    <div>

        頁面緩存的時間:<asp:LabelID="Label1" runat="server" Text="Label"></asp:Label>

    </div>

    <div>

        真實(緩存替換)的時間:

        <asp:PlaceHolderID="PlaceHolder1" runat="Server"></asp:PlaceHolder>

    </div>

    </form>

</body>

 

</html>

 

 

    頁面後臺CS代碼:   

protected void Page_Load(object sender, EventArgs e)

{

    //建立一個Substitution

    Substitution Substitution1 =new Substitution();

    //指定調用的回調方法名

    Substitution1.MethodName = "GetCurrentDateTime";           

    PlaceHolder1.Controls.Add(Substitution1);       

 

    Label1.Text=DateTime.Now.ToString();   

}

public staticstring GetCurrentDateTime(HttpContext context)

{

    return DateTime.Now.ToString();

}

 

 

如上代碼所示,頁面使用@ OutputCache指令設置了輸出緩存功能,其配置數據緩存過時時間爲60秒。然而,頁面其餘內容都被緩存,經過Substitution調用的回調方法顯示的內容是不被緩存的。