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

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

什么是緩存?

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

緩存在用于提高 ASP 性能方面是非常重要的,因為 ASP 的頁面和控件是都動態(tài)生成的。這對于交互相關的數(shù)據(jù)是極其重要的,因為響應時間是很寶貴的。

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

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

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

  • 如果它的生命周期已結束,
  • 如果該應用釋放了它的內存,
  • 如果由于某些原因緩存沒有被替換。

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

ASP.NET 中的緩存

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

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

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

輸出緩存

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

OutputCache 指令負責輸出緩存。它啟用輸出緩存,并對其行為提供一定程度的控制。

OutputCache 指令的語法:

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

把這個指令放在頁面指令下。這告訴環(huán)境需要緩存頁面,持續(xù) 15 秒。以下頁面加載事件處理程序將幫助確認頁面是否已被緩存完畢。

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()方法使特定時間內的進程停止。在這個例子中,線程停止了 10 秒鐘,因此,當頁面第一次下載時,需要花費 10 秒鐘的時間。然而,下次刷新頁面的時候,就不會花費時間了,因為這個頁面已經(jīng)從緩存中獲取了,不要再下載。

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

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

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

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í)行的時候,ASP 在文本框中依據(jù)名字緩存頁面。

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

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

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

實例

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

在這個實例中,我們給頁面添加一個標簽,這個標簽可以顯示頁面的回應時間。

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

除了這個標簽,整個頁面和數(shù)據(jù)訪問教程是一樣的。為這個頁面添加一個事件處理器,來下載時間。

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

設計的頁面應該是如下這個樣子的:

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

當你第一次執(zhí)行頁面時,并沒有發(fā)生什么不同。標簽顯示,每次刷新頁面,頁面會重新加載,而且在標簽上會顯示時間的變化。

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

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

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

對象緩存

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

Cache["key"] = item;

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

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

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

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

實例

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

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/>";
}

當頁面第一次加載時,會顯示:

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

如果你在 30 秒鐘內再次點擊按鈕,雖然頁面被刪除了,但是標簽控件會從緩存中得到信息,如下所示:

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