1 ASP.NET緩衝
(1) 緩衝技術概述
在網站應用程式中,網站的應用程式可以將頻繁訪問的資料以及需要大量處理時間來建立的資料存放區在記憶體中,從而提高網站的整體效能。例如,如果應用程式使用複雜的邏輯來處理大量資料,然後再將資料作為使用者頻繁訪問的報表返回,避免在使用者每次請求資料時重新建立報表可以提高效率。同樣,如果應用程式套件組合含一個處理複雜資料但不需要經常更新的頁,則在每次請求時伺服器都重新建立該頁會使工作效率低下。
說明:為了提高應用程式的效能,ASP.NET使用兩種基本的緩衝機制來提供緩衝功能。第一種機制是應用程式緩衝,它允許緩衝所產生的資料,如DataSet或自訂報表業務對象。第二種機制是頁輸出緩衝,它儲存頁處理輸出,並在使用者再次請求該頁時,重用所儲存的輸出,而不是再次處理該頁。
頁輸出緩衝:頁輸出緩衝在記憶體中儲存處理後的ASP.NET頁的內容。這一機制允許ASP.NET向用戶端發送頁響應,而不必再次經過頁處理生命週期。頁輸出緩衝對於那些不經常更改,但需要大量處理才能建立的頁特別有用。
應用程式緩衝:應用程式緩衝提供了一種編程方式,可通過鍵/值對將任意資料存放區在記憶體中。使用應用程式緩衝的優點是由ASP.NET管理緩衝,它會在項到期、無效或記憶體不足時移除緩衝中的項。還可以配置應用程式緩衝,以便在移除項時通知應用程式。
(2) 緩衝新增功能
緩衝設定檔:緩衝設定檔能夠在應用程式的web.config檔案中建立緩衝設定,然後在單個頁上引用這些設定。可以將緩衝設定同時應用於多頁。例如,可以定義一個緩衝設定檔,它將頁的緩衝期間設定為一天,然後可以配置各個頁使用這個緩衝設定檔,並且這些頁的緩衝期間為一天。如果將某個緩衝設定檔更改為不使用緩衝,將停止緩衝這些頁。
自訂緩衝依賴項:在ASP.NET 2.0中,可以根據應用程式特定情況建立自己的自訂緩衝依賴項。若要建立自訂緩衝依賴項,需要從CacheDependency繼承的類並在自訂類中實現自己的依賴項方法。例如,可以建立在Web服務中輪詢資料的依賴項。資料發生變化時,使快取資料無效。
SqlCacheDependency:ASP.NET 2.0引入了SqlCacheDependency類,它能夠在緩衝中配置一個項,以便在SQL Server資料庫中的表或行上擁有依賴項。當表中或特定行中發生更改時,具有依賴項的快取項目便會失效並從緩衝中移除。ASP.NET 2.0能夠在SQL Server 7.0、SQL Server 2000和SQL Server 2005中設定表的依賴項。使用SQL Server 2005時,還可以設定特定記錄的依賴項。
緩衝後替換:ASP.NET 2.0現在支援緩衝後替換,它能夠將頁中的某一部分配置不可緩衝。因此,儘管緩衝了該頁,但在再次請求該頁時,將重新處理它的部分內容。
(3) 緩衝配置
緩衝的配置可以通過多種方式來實現,這幾種方式分別為設定檔配置、單個頁面配置和使用者控制項的配置。
注意:設定檔配置主要是指可以在應用程式配置階層的任何設定檔中配置網頁輸出快取設定,包括machine.config檔案或特定於應用程式的web.config檔案。
單個頁面配置是指可以在單個頁面中以聲明方式或編程方式設定緩衝選項,還可將在設定檔中建立的緩衝設定檔應用於單個頁面。使用者控制項配置是指可以在單個使用者控制項中以聲明方式或編程方式設定緩衝,對於在其他情況下不緩衝的頁面內容來說,這是一種簡便的緩衝方法。
設定檔配置:由於machine.config檔案的配置方法與web.config檔案配置類似,所以這裡只介紹如何配置web.config檔案使用緩衝。在web.config檔案中,有兩個頂級配置節用於頁輸出緩衝:OutputCacheSection和OutputCacheSettingsSection。OutputCacheSection節用於配置應用程式範圍的設定,例如是否啟用還是禁用頁輸出緩衝。可以向OutputCacheSection添加enableOutputCache="false"來對整個應用程式禁用頁輸出緩衝。由於設定檔中的設定要優先於單個頁面中的緩衝設定,因此,樣本設定將導致不使用輸出緩衝。OUtputCacheSettingsSection用於配置可由單個頁面使用的設定檔和依賴項。例如,下面的代碼建立了一個名為CacheProfile1的OutputCacheProfiles,它將實現快取頁面60秒:
<outputCacheSettings>
<outputCacheProfiles>
<add name="CacheProfile1" duration="60" />
</outputCacheProfiles>
</outputCacheSettings>
頁面緩衝配置設定:通過應用在設定檔中定義的緩衝設定檔,可以配置單個頁中的緩衝。也可以在@OutputCache指令中配置單個緩衝屬性,或者通過設定頁的類定義中的屬性(attribute)進行設定。
使用者控制項緩衝配置設定:通過設定使用者控制項檔案中的@OutputCache指令,或設定控制項類定義中的PartialCachingAttribute屬性,可以對使用者控制項緩衝進行配置。
2 ASP.NET 頁面緩衝
ASP.NET可以緩衝ASP.NET頁所產生的部分響應或所有響應,在ASP.NET中將這種技術稱為頁面緩衝。
說明:頁面緩衝技術包括如何配置聲明和如何編程設定,頁面可以設定緩衝的到期時間,以及檢查快取頁面的有效性。同時,頁面緩衝可以快取頁面面的版本以及快取頁面面的不同部分。
(1) 聲明頁面緩衝
可以通過兩種方式聲明頁面緩衝,一種方式是在每個頁面中直接聲明,另一種方式是在設定檔中定義緩衝的配置屬性,然後在每個頁面設定該屬性。
使用在頁面直接聲明的方式聲明頁面緩衝的時候,需要在頁中包含@OutputCache指令,並定義Duration和VaryByParam屬性。在@OutputCache指令中包含Location屬性,並將其值定義為OutputCacheLocation枚舉中的下列值之一:Any、Client、Downstream、Server、ServerAndClient或None。下面的代碼示範如何將頁的可緩衝性設定為60秒:
<%@ OutputCache Duration="60" VaryByParam="None" %>
另一種凡是是通過設定檔聲明為統一的緩衝策略,然後在每個頁面再分別繼承。在應用程式的設定檔web.config中定義緩衝設定檔,在設定檔中包括duration和varyByParam設定,如以下代碼所示:
<caching>
<outputCacheSettings>
<outputCacheProfiles>
<add name="DemoTest" duration="30" varyByParam="none" />
</outputCacheProfiles>
</outputCacheSettings>
</caching>
在使用設定檔的每個ASP.NET頁中的包含@OutputCache指令,並將CacheProfile屬性設定為web.config檔案中定義的緩衝設定檔的名稱:
<%@ OutputCache CacheProfile="DemoTest" %>
(2) 編程設定頁面可緩衝性
可以通過編程的方式設定頁面的可緩衝性,如果應用程式是在運行時進行緩衝設定的,可以參考下面的編程方式進行設定。在頁面的代碼中,調用Response對象的Cache屬性的SetCacheability方法。
Response.Cache.SetCacheability(HttpCacheability.Public);
(3) 設定頁面緩衝到期時間
在ASP.NET中,如果想設定頁面緩衝的到期時間,可以通過聲明的方式和編程的方式來進行設定。
技巧:通過聲明方式設定頁面的緩衝到期時間,需要將@OutputCache指令包括在要緩衝其響應的ASP.NET頁中。將Duration屬性設定為一個正數值,將VaryByParam屬性設定為一個值。
技巧:通過編程方式進行設定,可以在頁面的後台代碼中,通過Response對象的Cache屬性設定該頁的到期策略,如以下代碼所示:
Response.Cache.SetExpires(DateTime.Now.AddSeconds(60));
Response.Cache.SetCacheability(HttpCacheability.Public);
Response.Cache.SetValidUntilExpires(true);
(4) 快取頁面有效性檢查
使用者請求快取頁面時,ASP.NET根據該頁中定義的緩衝策略來確定緩衝輸出是否仍然有效。如果緩衝輸出有效,則將輸出發送到用戶端,並且不重新處理該頁。ASP.NET提供了使用驗證回調在該驗證檢查期間運行代碼的功能,可以編寫自訂邏輯來檢查該頁是否有效。利用驗證回調,可以使在使用緩衝依賴項的正常進程之外的快取頁面無效。下面的例子中,示範了如何?這種方式的有效性檢查過程:
protected void Page_Load(object sender, EventArgs e)
{
//添加回調緩衝
Response.Cache.AddValidationCallback(new HttpCacheValidateHandler(ValidateCacheOutput), null);
}
public static void ValidateCacheOutput(HttpContext context, Object data, ref HttpValidationStatus status){
//判斷請求中是否包含Status對象
if(context.Request.QueryString["Status"] != null){
//取出Status對象的值
string pageStatus=context.Request.QueryString["Status"];
//判斷Status值的內容是否為invalid
if(pageStatus=="invalid")
status=HttpValidationStatus.Invalid;
//判斷Status值的內容是否為ignore
else if(pageStatus=="ignore")
status=HttpValidationStatus.IgnoreThisRequest;
else
status=HttpValidationStatus.Valid;
}
//如果不存在Status值,則顯示不正確
else
status=HttpValidationStatus.Valid;
}
(5) 快取頁面面版本
在實際的開發中,會基於請求為該頁建立不同的版本。例如,根據查詢字串中傳遞的值,該頁可能具有不同的輸出。ASP.NET允許在輸出緩衝中緩衝同一頁的多個版本。輸出緩衝可能會因下面的幾個因素而異:初始請求中的查詢字串、回送時傳遞的控制值、隨請求傳遞的HTTP標題、發出請求的瀏覽器的主要版本號。
技巧:可以通過以下兩種方法來快取頁面輸出的多個版本:使用@OutputCache指令屬性的聲明方式,或者使用HttpCachePolicy類的編程方式。
@OutputCache指令包括4個可用來快取頁面輸出的多個版本的屬性:
VaryByParam屬性可用來使緩衝輸出因查詢字串而異的緩衝情況。使用樣本如下所示:
<%@ OutputCache Duration="60" VaryByParam="Param1" %>
VaryByControl屬性可用來使緩衝輸出因控制值而異的緩衝情況。使用樣本如下所示:
<%@ OutputCache Duration="60" VaryByControl="Label1;Label2;Label3" %>
VaryByHeader屬性可用來使緩衝輸出因請求的HTTP標題而異的緩衝情況。使用樣本如下所示:
<%@ OutputCache Duration="60" VaryByParam="None" VaryByHeader="Accept-Language" %>
VaryByCustom屬性可用來使緩衝牲畜因瀏覽器類型或定義的自訂字串而異的緩衝情況。使用樣本如下所示:
<%@ OutputCache Duration="60" VaryByParam="None" VaryByCustom="browser" %>
3 緩衝應用程式資料
ASP.NET提供了一個強大的、便於使用的緩衝機制,用於將需要大量伺服器資源來建立的Object Storage Service在記憶體中。緩衝這些類型的資源會大大改進應用程式的效能。
說明:緩衝是由Cache類實現的,緩衝執行個體是每個應用程式專用的。緩衝生存期依賴於應用程式的生存期,重新啟動應用程式後,將重新建立Cache對象。
(1) 快取項目的添加
可以通過多種方式實現快取項目的添加,這些方式包括:
通過鍵和值直接設定項,向緩衝添加項。
使用Insert方法向緩衝添加項。
向緩衝添加項並添加依賴項,以便當該依賴項更改時,將該項從緩衝中移除。可以基於其他快取項目、檔案和多個對象設定以來項。
將沒有到期策略的項添加到緩衝中。
向緩衝添加項,並定義緩衝的項的相對優先順序。
通過調用Add方法添加項。
通過鍵和值的方式,直接添加快取項目,添加的範例程式碼如下所示:
Cache["Test1"]="Test1";
使用Insert方法,向緩衝對象中添加快取項目,範例程式碼如下所示:
Cache.Insert("Test2","Test2");
向緩衝添加項並添加依賴項,範例程式碼如下所示:
string[] dependencies={"Test2"};
Cache.Insert("Test3","Test3",new System.Web.Caching.CacheDependency(null,dependencies));
添加有到期策略的快取項目,範例程式碼如下所示:
Cache.Insert("Test4","Test4",null,DateTime.Now.AddMinutes(1d),System.Web.Caching.Cache.NoSlidingExpiration);
添加有優先順序的快取項目,範例程式碼如下所示:
Cache.Insert("Test5","Test5",null,System.Web.Caching.Cache.NoAbsoluteExpiration,
System.Web.Caching.Cache.NoSlidingExpiration,System.Web.Caching.CacheItemPriority.High,null);
通過調用Add方法添加快取項目,範例程式碼如下所示:
string Test6=(string)Cache.Add("Test6","Test6",null,System.Web.Caching.Cache.NoAbsoluteExpiration,
System.Web.Caching.Cache.NoSlidingExpiration,System.Web.Caching.Cache.CacheItemPriority.Default,null);
(2) 快取項目的檢索
說明:從緩衝中檢索快取項目,應指定儲存快取項目的鍵。由於緩衝中所儲存的資訊為易失資訊,即該資訊可能由ASP.NET移除,因此在檢索快取項目的時候,需要先判斷該索引值對應的快取項目是否存在,再進行檢索。
下面的程式碼範例示範了如何確定名為CacheItem的項是否包含在緩衝中。如果在,則代碼會將該項的內容分配給名為cachedString的變數。如果該項不在緩衝中,則代碼會將它添加到緩衝中,然後將它分配給cachedString。範例程式碼如下:
string cachedString;
//判斷CacheItem緩衝是否為空白
if(Cache["CacheItem"]!=null)
{
//擷取CacheItem值的緩衝內容
cachedString=(string)Cache["CacheItem"];
}
else
{
//添加CacheItem緩衝值
Cache.Insert("CacheItem","Hello,World.");
cachedString=(string)Cache["CacheItem"];
}
(3) 快取項目的刪除
ASP.NET緩衝中的資料是易失的,即不能永久儲存。緩衝自動移除的原因可能是因為緩衝已滿、該項已到期或者依賴項發生更改。
技巧:除了允許從緩衝中自動移除項之外,還可以顯式移除項。如果要顯示的刪除指定索引值的快取項目,可以通過調用Remove方法,以傳遞要移除的項的鍵。範例程式碼如下所示:
Cache.Remove("Test1");
4 快取項目操作樣本
對應的源視圖控制項的HTML代碼如下所示:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="AddCache.aspx.cs" Inherits="AddCache" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>無標題頁</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="直接設定Cache" /> <asp:Button
ID="Button8" runat="server" OnClick="Button8_Click" Text="移除" /><br />
<asp:Button ID="Button2" runat="server" OnClick="Button2_Click" Text="Insert設定Cache" />
<asp:Button ID="Button9" runat="server" OnClick="Button9_Click" Text="移除" /><br />
<asp:Button ID="Button3" runat="server" OnClick="Button3_Click" Text="設定Cache依賴項為其他Cache項" />
<asp:Button ID="Button10" runat="server" OnClick="Button10_Click" Text="移除" /><br />
<asp:Button ID="Button4" runat="server" Text="設定Cache依賴項為檔案" OnClick="Button4_Click" /> <asp:Button
ID="Button11" runat="server" OnClick="Button11_Click" Text="移除" /><br />
<asp:Button ID="Button6" runat="server" OnClick="Button6_Click" Text="添加有到期設定的緩衝" /> <asp:Button
ID="Button12" runat="server" OnClick="Button12_Click" Text="移除" /><br />
<asp:Button ID="Button5" runat="server" OnClick="Button5_Click" Text="添加有優先順序的快取項目" />
<asp:Button ID="Button13" runat="server" OnClick="Button13_Click" Text="移除" /><br />
<br />
<br />
<asp:Button ID="Button7" runat="server" OnClick="Button7_Click" Text="擷取快取項目" />
<br />
<br />
<asp:Label ID="Label1" runat="server"></asp:Label></div>
</form>
</body>
</html>
在頁面的後台中,添加對各個按鈕控制項的事件:
//直接設定Cache按鈕事件
protected void Button1_Click(object sender, EventArgs e)
{
Cache["Mode1"] = "直接設定Cache";
}
//移除該緩衝按鈕事件
protected void Button8_Click(object sender, EventArgs e)
{
Cache.Remove("Mode1");
}
//通過Insert方法設定Cache按鈕事件
protected void Button2_Click(object sender, EventArgs e)
{
Cache.Insert("Mode2", "Insert設定Cache");
}
//移除該緩衝按鈕事件
protected void Button9_Click(object sender, EventArgs e)
{
Cache.Remove("Mode2");
}
//添加依賴於Mode2快取項目的快取項目Mode3
protected void Button3_Click(object sender, EventArgs e)
{
string[] dependencies = { "Mode2" };
Cache.Insert("Mode3", "Mode2",
new System.Web.Caching.CacheDependency(null, dependencies));
}
//移除該緩衝按鈕事件
protected void Button10_Click(object sender, EventArgs e)
{
Cache.Remove("Mode3");
}
//添加依賴於檔案XMLFile.xml的快取項目
protected void Button4_Click(object sender, EventArgs e)
{
Cache.Insert("Mode4", "檔案快取依賴項",
new System.Web.Caching.CacheDependency(Server.MapPath("XMLFile.xml")));
}
//移除該緩衝按鈕事件
protected void Button11_Click(object sender, EventArgs e)
{
Cache.Remove("Mode4");
}
//設定有到期設定的快取項目
protected void Button6_Click(object sender, EventArgs e)
{
Cache.Insert("Mode5", "有到期時間的快取項目",
null, System.Web.Caching.Cache.NoAbsoluteExpiration,
new TimeSpan(0, 10, 0));
}
//移除該緩衝按鈕事件
protected void Button12_Click(object sender, EventArgs e)
{
Cache.Remove("Mode5");
}
//設定有優先順序的快取項目
protected void Button5_Click(object sender, EventArgs e)
{
Cache.Insert("Mode6", "設定優先權的快取項目",
null, System.Web.Caching.Cache.NoAbsoluteExpiration,
System.Web.Caching.Cache.NoSlidingExpiration,
System.Web.Caching.CacheItemPriority.High, null);
}
//移除該緩衝按鈕事件
protected void Button13_Click(object sender, EventArgs e)
{
Cache.Remove("Mode6");
}
//將頁面中所有的快取項目索引值資訊全部顯示出來
protected void Button7_Click(object sender, EventArgs e)
{
StringBuilder sb = new StringBuilder();
IDictionaryEnumerator CacheEnum = Cache.GetEnumerator();
while (CacheEnum.MoveNext())
{
sb.Append("Cache鍵--");
sb.Append(CacheEnum.Key);
sb.Append("Cache值--");
sb.Append(CacheEnum.Value);
sb.Append("<br/>");
}
this.Label1.Text = sb.ToString();
}
由於快取項目Mode4依賴於一個外部檔案XMLFile.xml,所以在網站下需要添加一個名稱為XMLFile.xml的XML檔案,當修改該檔案內容的時候,快取項目失敗。