C# ASP.NET系統快取全解析

隨夢而飛發表於2014-08-12

原文:http://blog.csdn.net/wyxhd2008/article/details/8076105

目錄(?)[-]

系統快取有什麼好處呢?舉個簡單的例子,你想通過網頁查詢某些資料,而這些資料並非實時變化,或者變化的時間是有期限的。例如查詢一些歷史資料。那麼每個使用者每次查的資料都是一樣的。如果不設定快取,ASP.NET也會根據每個使用者的請求重複查詢n次,這就增加了不必要的開銷。所以,可能的情況下儘量使用快取,從記憶體中返回資料的速度始終比去資料庫查的速度快,因而可以大大提供應用程式的效能。畢竟現在記憶體非常便宜,用空間換取時間效率應該是非常划算的。尤其是對耗時比較長的、需要建立網路連結的資料庫查詢操作等。快取功能是大型網站設計一個很重要的部分。由資料庫驅動的Web應用程式,如果需要改善其效能,最好的方法是使用快取功能。 

系統快取全解析1:系統快取的概述 

1     快取的分類     從分佈上來看,我們可以概括為客戶端快取和伺服器端快取。如圖所示:


客戶端快取—— 這點大家都有直觀的印象。比如你去一個新的網站,第一次可能要花一陣子時間才能載入整個頁面。而以後再去呢,時間就會大大的縮短,原因就在於這個客戶端快取。現在的瀏覽器都比較智慧,它會在客戶機器的硬碟上保留許多靜態的檔案,比如各種gif,jpeg檔案等等。等以後再去的時候,它會盡量使用本地快取裡面的檔案。只有伺服器端的檔案更新了,或是快取裡面的檔案過期了,它才會再次從伺服器端下載這些東西。很多時候是IE替我們做了這件事情。 

伺服器端快取—— 有些東西沒法或是不宜在客戶端快取,那麼我們只好在伺服器端想想辦法了。伺服器端快取從性質上看,又可以分為兩種。

  1. 靜態檔案快取

    好多頁面是靜態的,很少改動,那麼這種檔案最適於作靜態快取。現在的IIS 6.0這部分內容是直接存放在Kernel的記憶體中,由HTTP.SYS直接管理。由於它在Kernel Space,所以它的效能非常的高。使用者的請求如果在快取裡面,那麼HTTP.SYS直接將內容傳送到networkdriver上去,不需要像以前那樣從IISUser space的記憶體copyKernel中,然後再傳送到TCP/IP stack上。Kernellevel cache幾乎是現在高效能Web server的一個必不可少的特性。

  2. 動態快取

    動態快取是比較有難度的。因為你在快取的時候要時刻注意一個問題,那就是快取的內容是不是已經過時了。因為內容過時了可能會有很嚴重的後果。比如網上買賣股票的網站。你給別人提供的價格是過時的,那人家非砍了你不可。快取如何發現自己是不是過時就是一個非常複雜的問題。

    ASP.NET中,常見的動態快取主要有以下幾種手段:

  Ø  傳統快取方式

  Ø  頁面輸出快取。

  Ø  頁面區域性快取。

  Ø  利用.NET提供的System.Web.Caching 快取。

  Ø  快取依賴。

2  傳統快取方式

比如將可重複利用的東西放到Application或是Session中去儲存。

 Session["Style"] = val;
 Application["Count"] =0;

系統快取全解析2:頁面輸出快取

頁面輸出快取是最為簡單的快取機制,該機制將整個ASP.NET頁面內容儲存在伺服器記憶體中。當使用者請求該頁面時,系統從記憶體中輸出相關資料,直到快取資料過期。在這個過程中,快取內容直接傳送給使用者,而不必再次經過頁面處理生命週期。通常情況下,頁面輸出快取對於那些包含不需要經常修改內容的,但需要大量處理才能編譯完成的頁面特別有用。需要讀者注意的是,頁面輸出快取是將頁面全部內容都儲存在記憶體中,並用於完成客戶端請求。

ASP.NET中頁面快取的使用方法非常的簡單,只需要在aspx頁的頂部加這樣一句宣告即可:<%@ OutputCache Duration="60" VaryByParam="none" %>其中Duration 表示快取的時間(秒)。這是必選屬性。如果未包含該屬性,將出現分析器錯誤。

 

如下面的例子:

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

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

<!DOCTYPE html>

 

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

<head runat="server">

<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

<title></title>

</head>

<body>

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

<div>

&nbsp;</div>

<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>

</form>

</body>

</html>

後置程式碼為:

public partial class WebForm1 : System.Web.UI.Page

{

protected void Page_Load(object sender, EventArgs e)

{

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

}

}

這樣:每次重新整理頁面的時間並不變化,60秒後才變化一次,說明資料被快取了60秒。

引數:VaryByParam

是指頁面根據使用 POST GET 傳送的名稱/值對(引數)來更新快取的內容,多個引數用分號隔開。如果不希望根據任何引數來改變快取內容,請將值設定為 none。如果希望通過所有的引數值改變都更新快取,請將屬性設定為星號 (*)

例如: http://localhost:1165/16-4-3/WebForm1.aspx?p=1 
則可以在WebForm1.aspx頁面頭部宣告快取:<%@OutputCacheDuration="60"VaryByParam="p" %>

以上程式碼設定頁面快取時間是60秒,並根據p引數的值來更新快取,即p的值發生變化才更新快取。

如果一直是WebForm1.aspx?p=1訪問該頁,則頁面會快取當前資料,當p=2時又會執行後臺程式碼更新快取內容。

   

如果有多個引數時,如:http://localhost:1165/16-4-3/WebForm1.aspx?p=1&n=1

可以這樣宣告:<%@OutputCacheDuration="60"VaryByParam="p;n" %> 

除此之外,@OutputCache 還有一些其他的屬性。@OutputCache指令中的屬性引數描述如下:

   

<%@ OutputCache Duration="#ofseconds"

   Location="Any | Client | Downstream | Server | None |

     ServerAndClient "

   Shared="True | False"

   VaryByControl="controlname"

   VaryByCustom="browser | customstring"

   VaryByHeader="headers"

   VaryByParam="parametername"

   CacheProfile="cache profile name | ''"

   NoStore="true | false"

   SqlDependency="database/table name pair | CommandNotification"

 %> 

 CacheProfile

用於呼叫Web.config配置檔案中設定的快取時間。這是可選屬性,預設值為空字元 ("")

例如:

Web.config中加入配置:

<system.web>

    <caching>

        <outputCacheSettings>

            <outputCacheProfiles>

                <addname="CacheTest"duration="50" />

            </outputCacheProfiles>

        </outputCacheSettings>

</caching>

</system.web> 

       頁面中宣告:

 <%@ OutputCache CacheProfile="CacheTest"  VaryByParam="none" %>

 注意:

包含在使用者控制元件(.ascx 檔案)中的 @ OutputCache 指令不支援此屬性。在頁中指定此屬性時,屬性值必須與 outputCacheSettings 節下面的 outputCacheProfiles 元素中的一個可用項的名稱匹配。如果此名稱與配置檔案項不匹配,將引發異常。

 如果每個頁面的快取時間相同,則不需要每個頁面設定,而是通過統一一個地方控制,這樣就可以更好的統一控制所有頁面的快取時間。如果想改變快取時間,只需要改一下web.config的配置資訊即可,而不用每個頁面去修改。 

VaryByControl

通過使用者控制元件檔案中包含的伺服器控制元件來改變快取(值是控制元件ID,多控制元件用分號隔開)。

ASP.NET 頁和使用者控制元件上使用 @ OutputCache 指令時,需要該屬性或 VaryByParam屬性。

   

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

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

   

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

<head runat="server">

    <title>根據控制元件頁面快取</title>

</head>

<body>

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

    <div>

         <%=DateTime.Now %>       

        <br>

    <asp:DropDownList ID="DropDownList1" runat="server">

        <asp:ListItem>beijing</asp:ListItem>

        <asp:ListItem>shanghai</asp:ListItem>

        <asp:ListItem>guangzhou</asp:ListItem>

        </asp:DropDownList>

        <asp:Button ID="Button1" runat="server" Text="提交" />

    </div>

    </form>

</body>

   

</html>

   

以上程式碼設定快取有效期是60秒,並且頁面不隨任何GETPOST引數改變(即使不使用VaryByParam屬性,但是仍然需要在@ OutputControl指令中顯式宣告該屬性)。如果使用者控制元件中包含ID屬性為"DropDownList1"的伺服器控制元件(例如下拉框控制元件),那麼快取將根據該控制元件的變化來更新頁面資料。

 

 

 

 

相關文章