鍍金池/ 教程/ C#/ 數(shù)據(jù)緩存
調(diào)試
管理狀態(tài)
Panel 控件
Web 服務(wù)
語(yǔ)言集成查詢
數(shù)據(jù)源
基礎(chǔ)控件
廣告輪轉(zhuǎn)器
服務(wù)器端
服務(wù)器控件
ADO.NET
多線程
HTML 服務(wù)器
生命周期
Ajax 控制
客戶端
異常處理
環(huán)境設(shè)置
部署
個(gè)性化
驗(yàn)證器
多視圖
日歷
文件上傳
ASP.NET - 數(shù)據(jù)綁定
數(shù)據(jù)庫(kù)存取
實(shí)例
自定義控件
簡(jiǎn)介
配置
數(shù)據(jù)緩存
安全性
指令
事件處理

數(shù)據(jù)緩存

什么是緩存?

緩存是一種將經(jīng)常使用的數(shù)據(jù)/信息存儲(chǔ)在內(nèi)存中的技術(shù),這樣,下次需要相同的數(shù)據(jù)/信息時(shí),可以直接從內(nèi)存檢索,而不是再?gòu)膽?yīng)用程序中生成。

緩存在用于提高 ASP 性能方面是非常重要的,因?yàn)?ASP 的頁(yè)面和控件是都動(dòng)態(tài)生成的。這對(duì)于交互相關(guān)的數(shù)據(jù)是極其重要的,因?yàn)轫憫?yīng)時(shí)間是很寶貴的。

在需要快速訪問(wèn)的媒體,如計(jì)算機(jī)的隨機(jī)存取存儲(chǔ)器,緩存放置了被頻繁使用的數(shù)據(jù)。ASP 的運(yùn)行時(shí)間包含一個(gè)叫做緩存的 CLR 對(duì)象的鍵值對(duì)。它位于應(yīng)用程序內(nèi),并且通過(guò) HttpContext 和 System.Web.UI.Page 可用。

在某些方面,緩存和存儲(chǔ)狀態(tài)對(duì)象有相似之處。然而,狀態(tài)對(duì)象的存儲(chǔ)信息是確定的,比如,你可以計(jì)算存儲(chǔ)在狀態(tài)對(duì)象的數(shù)據(jù),但是緩存的數(shù)據(jù)是不確定的。

在下列情況里,數(shù)據(jù)是不可用的:

  • 如果它的生命周期已結(jié)束,
  • 如果該應(yīng)用釋放了它的內(nèi)存,
  • 如果由于某些原因緩存沒(méi)有被替換。

您可以使用一個(gè)索引器在緩存中訪問(wèn)項(xiàng)目,并且有可能控制緩存中對(duì)象的生命周期和設(shè)置緩存的對(duì)象及其物理資源之間的聯(lián)系。

ASP.NET 中的緩存

ASP提供如下幾種不同類型的緩存:

  • 輸出緩存:輸出緩存可以存儲(chǔ)最后顯現(xiàn)的網(wǎng)頁(yè)的副本,或者是發(fā)送到客戶機(jī)的部分頁(yè)面。下次客戶機(jī)請(qǐng)求該頁(yè)面時(shí),這個(gè)頁(yè)面的緩存副本就會(huì)被發(fā)送給客戶機(jī),而不是重新生成這個(gè)頁(yè)面,這樣一來(lái)就節(jié)省了時(shí)間。
  • 數(shù)據(jù)緩存:數(shù)據(jù)緩存是指從數(shù)據(jù)源緩存數(shù)據(jù)。只要緩存沒(méi)被替換,那么再請(qǐng)求該數(shù)據(jù)時(shí)就會(huì)從緩存中獲取。當(dāng)緩存被替換的時(shí)候,會(huì)從數(shù)據(jù)源中獲取新數(shù)據(jù),緩存也會(huì)被再次充滿。
  • 對(duì)象緩存:對(duì)象緩存是緩存頁(yè)面的對(duì)象,比如數(shù)據(jù)綁定控件等。緩存的數(shù)據(jù)放在服務(wù)器的內(nèi)存。
  • 類緩存:網(wǎng)頁(yè)或 Web 服務(wù)是第一次運(yùn)行時(shí)在組裝編譯成頁(yè)類。然后組裝會(huì)在服務(wù)器緩存。當(dāng)下次請(qǐng)求該頁(yè)面或者服務(wù),就會(huì)使用緩存的裝配。當(dāng)改變?cè)创a時(shí),CLR 重新編譯程序集。
  • 配置緩存:應(yīng)用程序配置信息存儲(chǔ)在一個(gè)配置文件。配置緩存存儲(chǔ)在服務(wù)器內(nèi)存配置信息。

在本教程中,我們將考慮輸出緩存,數(shù)據(jù)緩存和對(duì)象緩存。

輸出緩存

呈現(xiàn)一個(gè)頁(yè)面可能涉及一些復(fù)雜的過(guò)程,如,數(shù)據(jù)庫(kù)訪問(wèn),呈現(xiàn)復(fù)雜的控件等。輸出緩存允許通過(guò)在內(nèi)存中緩存數(shù)據(jù),而繞過(guò)往返服務(wù)器。甚至可以緩存整個(gè)頁(yè)面。

OutputCache 指令負(fù)責(zé)輸出緩存。它啟用輸出緩存,并對(duì)其行為提供一定程度的控制。

OutputCache 指令的語(yǔ)法:

<%@ OutputCache Duration="15" VaryByParam="None" %>

把這個(gè)指令放在頁(yè)面指令下。這告訴環(huán)境需要緩存頁(yè)面,持續(xù) 15 秒。以下頁(yè)面加載事件處理程序?qū)椭_認(rèn)頁(yè)面是否已被緩存完畢。

protected void Page_Load(object sender, EventArgs e)
{
    Thread.Sleep(10000);  
    Response.Write("This page was generated and cache at:" +
    DateTime.Now.ToString());
}

Thread.Sleep()方法使特定時(shí)間內(nèi)的進(jìn)程停止。在這個(gè)例子中,線程停止了 10 秒鐘,因此,當(dāng)頁(yè)面第一次下載時(shí),需要花費(fèi) 10 秒鐘的時(shí)間。然而,下次刷新頁(yè)面的時(shí)候,就不會(huì)花費(fèi)時(shí)間了,因?yàn)檫@個(gè)頁(yè)面已經(jīng)從緩存中獲取了,不要再下載。

當(dāng)幫助控制輸出緩存的行為 OutputCache 指令有以下特性:

屬性 描述
DiskCacheable true/false 描述輸出是否可以寫入帶有緩存的磁盤。
NoStore true/false 描述 "no store" 緩存頭部是否被發(fā)送。
CacheProfile 字符串名 存儲(chǔ)在 web.config 中的緩存配置文件名字。
VaryByParam None
*
參數(shù)名
GET 請(qǐng)求中使用分號(hào)分隔的字符串值或者是 POST 請(qǐng)求中的變量值。
VaryByHeader *
頭文件名
可能是由客戶端提交的用分號(hào)分隔的指定頭的字符串。
VaryByCustom 瀏覽器
自定義字符串
通知 ASP.NET 通過(guò)瀏覽器名字版本或者客戶端字符串改變輸出緩存。
Location 任何
客戶端
下載流
服務(wù)器
None
任何:頁(yè)面可能緩存在任何位置
客戶端:緩存內(nèi)容包含在瀏覽器中
下載流:緩存內(nèi)容保存在下載流和服務(wù)器中
服務(wù)器:緩存僅保存在服務(wù)器之中
None:不允許緩存。
Duration 數(shù)字 被緩存頁(yè)面或者操作的秒數(shù)。

讓我們?yōu)榍懊娴氖纠砑右粋€(gè)文本框和一個(gè)按鈕,并添加這個(gè)按鈕的事件處理程序。

protected void btnmagic_Click(object sender, EventArgs e)
{
    Response.Write("<br><br>");
    Response.Write("<h2> Hello, " + this.txtname.Text + "</h2>");
}

改變 OutputCache 指令:

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

程序執(zhí)行的時(shí)候,ASP 在文本框中依據(jù)名字緩存頁(yè)面。

數(shù)據(jù)緩存

數(shù)據(jù)緩存的主要方面是數(shù)據(jù)源控件緩存。我們已經(jīng)討論了數(shù)據(jù)源控件代表一個(gè)數(shù)據(jù)源中的數(shù)據(jù),如數(shù)據(jù)庫(kù)或 XML 文件。這些控件從抽象類 DataSourceControl 中派生,并有以下繼承屬性以實(shí)現(xiàn)緩存:

  • 緩存期 — 為緩存數(shù)據(jù)的數(shù)據(jù)源計(jì)時(shí)。
  • 緩存期滿策略 — 定義了當(dāng)數(shù)據(jù)在緩存中過(guò)期時(shí),緩存的行為。
  • 緩存值依賴 — 定義了一個(gè)控件值,這個(gè)控件可以在數(shù)據(jù)期滿時(shí)自動(dòng)將其移出緩存。
  • 啟用緩存 — 可以確認(rèn)是否緩存了數(shù)據(jù)。

實(shí)例

為了演示數(shù)據(jù)緩存,我們創(chuàng)建一個(gè)新的網(wǎng)站,在上面添加一個(gè)新的網(wǎng)絡(luò)表單。在數(shù)據(jù)庫(kù)中添加一個(gè)連接數(shù)據(jù)訪問(wèn)教程的 SqlDataSource 控件。

在這個(gè)實(shí)例中,我們給頁(yè)面添加一個(gè)標(biāo)簽,這個(gè)標(biāo)簽可以顯示頁(yè)面的回應(yīng)時(shí)間。

<asp:Label ID="lbltime" runat="server"></asp:Label>

除了這個(gè)標(biāo)簽,整個(gè)頁(yè)面和數(shù)據(jù)訪問(wèn)教程是一樣的。為這個(gè)頁(yè)面添加一個(gè)事件處理器,來(lái)下載時(shí)間。

protected void Page_Load(object sender, EventArgs e)
{
    lbltime.Text = String.Format("Page posted at: {0}", DateTime.Now.ToLongTimeString());
}

設(shè)計(jì)的頁(yè)面應(yīng)該是如下這個(gè)樣子的:

http://wiki.jikexueyuan.com/project/asp-net/images/data_caching.jpg" alt="data_caching.jpg" />

當(dāng)你第一次執(zhí)行頁(yè)面時(shí),并沒(méi)有發(fā)生什么不同。標(biāo)簽顯示,每次刷新頁(yè)面,頁(yè)面會(huì)重新加載,而且在標(biāo)簽上會(huì)顯示時(shí)間的變化。

接下來(lái),把數(shù)據(jù)源控件的 EnableCaching 的屬性設(shè)置為“真”,將 Cacheduration 屬性設(shè)置為 “60”。它將實(shí)現(xiàn)緩存,緩存將每隔 60 秒到期。

每一次刷新,時(shí)間戳都會(huì)變化。但如果你在 60 秒之內(nèi)改變表中的數(shù)據(jù),在緩存到期之前將不會(huì)顯示。

<asp:SqlDataSource ID = "SqlDataSource1" runat = "server" 
   ConnectionString = "<%$ ConnectionStrings: ASPDotNetStepByStepConnectionString %>" 
    ProviderName = "<%$ ConnectionStrings: ASPDotNetStepByStepConnectionString.ProviderName %>" 
    SelectCommand = "SELECT * FROM [DotNetReferences]"
    EnableCaching = "true" CacheDuration = "60">         
</asp:SqlDataSource>

對(duì)象緩存

對(duì)象緩存比其他緩存技術(shù)提供了更大的靈活性。你可以利用對(duì)象緩存在緩存中放置任何對(duì)象。對(duì)象也可以是任意類型的 — 數(shù)據(jù)類型,網(wǎng)絡(luò)控件,類,數(shù)據(jù)設(shè)置對(duì)象等等。僅僅需要給這些項(xiàng)目分配一個(gè)值名,它們就可以被添加到緩存中,就像下面展示的這樣:

Cache["key"] = item;

為了在緩存中插入對(duì)象, ASP 提供了 Insert() 方法。這種方法有四種重載版本。我們來(lái)看一下:

重載 描述
Cache.Insert((key, value); 以鍵值對(duì)的方式插入緩存,優(yōu)先權(quán)和生命周期為默認(rèn) 。
Cache.Insert(key, value, dependencies); 以鍵值對(duì)的方式插入緩存,優(yōu)先權(quán)和生命周期為默認(rèn),和鏈接到其他文件或內(nèi)容的緩存依賴,這樣緩存修改就不再還有限的了。
Cache.Insert(key, value, dependencies, absoluteExpiration, slidingExpiration); 指出上述配置的有效期。
Cache.Insert(key, value, dependencies, absoluteExpiration, slidingExpiration, priority, onRemoveCallback); 與配置一起也允許設(shè)置緩存內(nèi)容的優(yōu)先權(quán)并委派,指出一種方法來(lái)調(diào)用當(dāng)一個(gè)對(duì)象移除時(shí)。

動(dòng)態(tài)生命周期使用于移除一個(gè)不作用于任何一個(gè)指定的時(shí)間跨度的緩存項(xiàng)。下面代碼段用來(lái)保存一個(gè)具有 10 分鐘滑動(dòng)生命周期的無(wú)依賴的緩存項(xiàng):

Cache.Insert("my_item", obj, null, DateTime.MaxValue, TimeSpan.FromMinutes(10));

實(shí)例

僅僅使用一個(gè)按鈕和一個(gè)標(biāo)簽創(chuàng)建一個(gè)頁(yè)面。在頁(yè)面加載事件中寫入如下代碼:

protected void Page_Load(object sender, EventArgs e)
{
    if (this.IsPostBack)
    {
        lblinfo.Text += "Page Posted Back.<br/>";
    }
    else
    {
        lblinfo.Text += "page Created.<br/>";
    }

    if (Cache["testitem"] == null)
    {
        lblinfo.Text += "Creating test item.<br/>";
        DateTime testItem = DateTime.Now;
        lblinfo.Text += "Storing test item in cache ";
        lblinfo.Text += "for 30 seconds.<br/>";
        Cache.Insert("testitem", testItem, null, 
        DateTime.Now.AddSeconds(30), TimeSpan.Zero);
    }
    else
    {
        lblinfo.Text += "Retrieving test item.<br/>";
        DateTime testItem = (DateTime)Cache["testitem"];
        lblinfo.Text += "Test item is: " + testItem.ToString();
        lblinfo.Text += "<br/>";
    }

    lblinfo.Text += "<br/>";
}

當(dāng)頁(yè)面第一次加載時(shí),會(huì)顯示:

Page Created.
Creating test item.
Storing test item in cache for 30 seconds.

如果你在 30 秒鐘內(nèi)再次點(diǎn)擊按鈕,雖然頁(yè)面被刪除了,但是標(biāo)簽控件會(huì)從緩存中得到信息,如下所示:

Page Posted Back.
Retrieving test item.
Test item is: 14-07-2010 01:25:04
上一篇:Panel 控件下一篇:語(yǔ)言集成查詢