系統快取全解析3:頁面區域性快取

iDotNetSpace發表於2009-07-02

有時快取整個頁面是不現實的,因為頁的某些部分可能在每次請求時都需要變化。在這些情況下,只能快取頁的一部分。顧名思義,頁面部分快取是將頁面部分內容儲存在記憶體中以便響應使用者請求,而頁面其他部分內容則為動態內容。頁面部分快取的實現包括兩種方式:控制元件快取和替換後快取

 

1. 控制元件快取(也稱為片段快取)

    這種方式允許將需要快取的資訊包含在一個使用者控制元件內,然後,將該使用者控制元件標記為可快取的,以此來快取頁面輸出的部分內容。該選項允許快取頁面中的特定內容,而沒有快取整個頁面,因此,每次都需重新建立整個頁。例如,如果要建立一個顯示大量動態內容(如股票資訊)的頁,其中有些部分為靜態內容(如每週總結),這時可以將靜態部分放在使用者控制元件中,並允許快取這些內容。

    在ASP.NET中,提供了UserControl這種使用者控制元件的功能。一個頁面可以通過多個UserControl來組成。只需要在某個或某幾個UserControl裡設定快取。

    例如:

    那麼可以在WebUserControl1.ascx的頁頭程式碼中新增宣告語句:

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

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

 

=DateTime.Now %>  

 

 

 

     呼叫該控制元件的頁面WebForm1.aspx程式碼:

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

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

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

<head runat="server">

    <title>控制元件快取title>

head>

<body>

    <form id="form1" runat="server">

    <div>

    頁面的:=DateTime.Now %>    

    div>

    <div>

    控制元件的:<uc1:WebUserControl1 ID="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" %>

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

<head runat="server">

    <title>快取後替換示例title>

head>

<body>

    <form id="form1" runat="server">

    <div>

    頁面快取的時間:= DateTime.Now.ToString() %>  

    div>

    <div>   

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

    div>

    form>

body>

 

html>

 

    頁面後臺程式碼:

public partial class 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" %>

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

<head runat="server">

    <title>快取後替換-Substitution控制元件API應用title>

head>

<body>

    <form id="form1" runat="server">

    <div>

        頁面快取的時間:<asp:Label ID="Label1" runat="server"Text="Label">asp:Label>

    div>

    <div>

        真實(快取替換)的時間:

        <asp:PlaceHolder ID="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 static string GetCurrentDateTime(HttpContext context)

{

    return DateTime.Now.ToString();

}

 

 

    如上程式碼所示,頁面使用@ OutputCache指令設定了輸出快取功能,其配置資料快取過期時間為60秒。然而,頁面其他內容都被快取,通過Substitution呼叫的回撥方法顯示的內容是不被快取的。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-608132/,如需轉載,請註明出處,否則將追究法律責任。

相關文章