什么是緩存?緩存技術(shù)是將經(jīng)常使用的數(shù)據(jù)/信息存儲(chǔ)在內(nèi)存中的技術(shù),以便下次需要相同的數(shù)據(jù)/信息時(shí),可以直接從內(nèi)存中檢索,而不是由應(yīng)用程序生成。
緩存對(duì)于提高ASP.NET性能非常重要,因?yàn)轫?yè)面和控件是在這里動(dòng)態(tài)生成的。這對(duì)于數(shù)據(jù)相關(guān)的事務(wù)尤其重要,因?yàn)檫@些事務(wù)在響應(yīng)時(shí)間上是昂貴的。
高速緩存將常用數(shù)據(jù)放置在快速訪問(wèn)的媒體中,例如計(jì)算機(jī)的隨機(jī)存取存儲(chǔ)器。 ASP.NET運(yùn)行時(shí)包含稱(chēng)為緩存的CLR對(duì)象的鍵值映射。 這駐留在應(yīng)用程序中,可通過(guò)HttpContext和System.Web.UI.Page獲取。
在某些方面,緩存類(lèi)似于存儲(chǔ)狀態(tài)對(duì)象。 然而,在狀態(tài)對(duì)象中存儲(chǔ)信息是確定性的,即可以指望存儲(chǔ)在那里的數(shù)據(jù),并且數(shù)據(jù)的緩存是非確定性的。
在以下情況下數(shù)據(jù)將不可用:
可以使用索引器訪問(wèn)緩存中的項(xiàng)目,并可以控制緩存中對(duì)象的生存期并設(shè)置緩存對(duì)象與其物理源之間的鏈接。
ASP.NET提供了以下不同類(lèi)型的緩存:
輸出緩存 - 輸出緩存存儲(chǔ)最終呈現(xiàn)的HTML頁(yè)面的副本或發(fā)送到客戶端的部分頁(yè)面。 當(dāng)下一個(gè)客戶請(qǐng)求這個(gè)頁(yè)面時(shí),不用重新生成頁(yè)面,而是發(fā)送頁(yè)面的緩存副本,從而節(jié)省時(shí)間。
數(shù)據(jù)緩存 - 數(shù)據(jù)緩存意味著緩存來(lái)自數(shù)據(jù)源的數(shù)據(jù)。只要緩存未過(guò)期,就會(huì)從緩存中滿足對(duì)數(shù)據(jù)的請(qǐng)求。 當(dāng)緩存過(guò)期時(shí),數(shù)據(jù)源獲取新的數(shù)據(jù),并重新填充緩存。
對(duì)象緩存 - 對(duì)象緩存緩存頁(yè)面上的對(duì)象,如數(shù)據(jù)綁定控件。 緩存的數(shù)據(jù)存儲(chǔ)在服務(wù)器內(nèi)存中。
類(lèi)緩存 - Web頁(yè)面或Web服務(wù)在第一次運(yùn)行時(shí)會(huì)匯編到程序集中的頁(yè)面類(lèi)中。然后程序集被緩存在服務(wù)器中。下一次請(qǐng)求頁(yè)面或服務(wù)時(shí),會(huì)引用緩存的程序集。 當(dāng)源代碼改變時(shí),CLR重新編譯程序集。
配置緩存 - 應(yīng)用程序范圍的配置信息存儲(chǔ)在配置文件中。 配置緩存將配置信息存儲(chǔ)在服務(wù)器內(nèi)存中。
在本教程中,我們將考慮輸出緩存,數(shù)據(jù)緩存和對(duì)象緩存。
渲染頁(yè)面可能涉及一些復(fù)雜的過(guò)程,如數(shù)據(jù)庫(kù)訪問(wèn),渲染復(fù)雜的控件等。輸出緩存允許通過(guò)緩存內(nèi)存中的數(shù)據(jù)繞過(guò)服務(wù)器往返。即使整個(gè)頁(yè)面也可以被緩存。
OutputCache指令負(fù)責(zé)輸出緩存。它啟用輸出緩存并提供對(duì)其行為的一定控制。
OutputCache指令的語(yǔ)法:
<%@ OutputCache Duration="15" VaryByParam="None" %>
把這個(gè)指令放在page指令下。這告訴環(huán)境緩存頁(yè)面15秒。 以下用于頁(yè)面加載的事件處理程序?qū)⒂兄跍y(cè)試頁(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)?shù)谝淮渭虞d頁(yè)面時(shí),需要10秒。 但是,下次刷新頁(yè)面時(shí),不需要任何時(shí)間,因?yàn)轫?yè)面是從緩存中檢索的而不是重新加載的。
OutputCache指令具有以下屬性,這有助于控制輸出緩存的行為:
| 編號(hào) | 屬性 | 值 | 描述 |
|---|---|---|---|
| 1 | DiskCacheable |
true/false |
指定可以將輸出寫(xiě)入基于磁盤(pán)的緩存。 |
| 2 | NoStore |
true/false |
指定是否發(fā)送“無(wú)存儲(chǔ)”緩存控制標(biāo)題。 |
| 3 | CacheProfile |
字符串名稱(chēng) | 要存儲(chǔ)在web.config中的緩存配置文件的名稱(chēng)。 |
| 4 | VaryByParam |
None * Param-name |
以分號(hào)分隔的字符串列表指定POST請(qǐng)求中或GET請(qǐng)求變量中的查詢字符串值。 |
| 5 | VaryByHeader |
*Header names |
以分號(hào)分隔的字符串列表指定可能由客戶端提交的標(biāo)頭。 |
| 6 | VaryByCustom |
瀏覽器 自定義字符串 | 告訴ASP.NET通過(guò)瀏覽器名稱(chēng)和版本或自定義字符串來(lái)改變輸出緩存。 |
| 7 | Location |
Any Client Downstream Server None | Any:頁(yè)面可能被緩存在任何地方。Client:緩存的內(nèi)容保留在瀏覽器中。Downstream:存儲(chǔ)在下游和服務(wù)器中的緩存內(nèi)容。Server:僅在服務(wù)器上保存的緩存內(nèi)容。 |
| 8 | Duration |
數(shù)字 | 頁(yè)面或控件被緩存的秒數(shù)。 |
添加一個(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.NET會(huì)根據(jù)文本框中的名稱(chēng)來(lái)緩存頁(yè)面。
數(shù)據(jù)緩存的主要方面是緩存數(shù)據(jù)源控件。 我們已經(jīng)討論過(guò),數(shù)據(jù)源控件代表數(shù)據(jù)源中的數(shù)據(jù),如數(shù)據(jù)庫(kù)或XML文件。這些控件派生自抽象類(lèi)DataSourceControl,并具有以下用于實(shí)現(xiàn)緩存的繼承屬性:
為了演示數(shù)據(jù)緩存,創(chuàng)建一個(gè)新的網(wǎng)站并在其上添加一個(gè)新的Web表單。 使用數(shù)據(jù)訪問(wèn)教程中已經(jīng)使用的數(shù)據(jù)庫(kù)連接添加一個(gè)SqlDataSource控件。
對(duì)于這個(gè)例子,添加一個(gè)標(biāo)簽到頁(yè)面,這將顯示頁(yè)面的響應(yīng)時(shí)間。
<asp:Label ID="lbltime" runat="server"></asp:Label>
內(nèi)容頁(yè)面除了標(biāo)簽之外,與數(shù)據(jù)訪問(wèn)教程中的內(nèi)容頁(yè)面相同。 為頁(yè)面加載事件添加一個(gè)事件處理程序:
protected void Page_Load(object sender, EventArgs e)
{
lbltime.Text = String.Format("Page posted at: {0}", DateTime.Now.ToLongTimeString());
}
設(shè)計(jì)好的頁(yè)面應(yīng)該如下所示:

當(dāng)您第一次執(zhí)行頁(yè)面時(shí),沒(méi)有什么不同,標(biāo)簽顯示,每次刷新頁(yè)面時(shí),頁(yè)面都會(huì)重新加載,并且標(biāo)簽上顯示的時(shí)間會(huì)發(fā)生變化。
接下來(lái),將數(shù)據(jù)源控件的EnableCaching屬性設(shè)置為true,并將Cacheduration屬性設(shè)置為60。 它將實(shí)現(xiàn)緩存,緩存將每60秒過(guò)期。
每次刷新都會(huì)更改時(shí)間戳,但如果在60秒內(nèi)更改了表中的數(shù)據(jù),則在緩存過(guò)期之前不會(huì)顯示該數(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>
對(duì)象緩存比其他緩存技術(shù)提供更多的靈活性。 可以使用對(duì)象緩存將任何對(duì)象放置在緩存中。 該對(duì)象可以是任何類(lèi)型 - 數(shù)據(jù)類(lèi)型,Web控件,類(lèi),數(shù)據(jù)集對(duì)象等。只需通過(guò)分配新的鍵名稱(chēng)即可將該項(xiàng)添加到緩存中,如下所示:
Cache["key"] = item;
ASP.NET還提供了將對(duì)象插入緩存的Insert()方法。 此方法有四個(gè)重載版本。如下所列 -
| 編號(hào) | 方法 | 描述 |
|---|---|---|
| 1 | Cache.Insert((key, value); |
使用鍵名稱(chēng)和值將項(xiàng)目插入高速緩存,默認(rèn)優(yōu)先級(jí)和到期。 |
| 2 | Cache.Insert(key, value, dependencies); |
將項(xiàng)目插入高速緩存中,其中包含鍵值,默認(rèn)優(yōu)先級(jí),到期時(shí)間以及鏈接到其他文件或項(xiàng)目的CacheDependency名稱(chēng),以便在更改緩存項(xiàng)目時(shí)不再有效。 |
| 3 | Cache.Insert(key, value, dependencies, absoluteExpiration, slidingExpiration); |
這表明與上述問(wèn)題一起的到期策略。 |
| 4 | Cache.Insert(key, value, dependencies, absoluteExpiration, slidingExpiration, priority, onRemoveCallback); |
這個(gè)參數(shù)和參數(shù)也允許設(shè)置緩存項(xiàng)目的優(yōu)先級(jí)和一個(gè)委托,指向一個(gè)方法被調(diào)用時(shí),該項(xiàng)目被刪除。 |
滑動(dòng)到期用于在指定的時(shí)間間隔內(nèi)未使用時(shí)從緩存中刪除項(xiàng)目。 以下代碼片段存儲(chǔ)滑動(dòng)過(guò)期時(shí)間為10分鐘,不具有依賴(lài)性。
Cache.Insert("my_item", obj, null, DateTime.MaxValue, TimeSpan.FromMinutes(10));
用一個(gè)按鈕和一個(gè)標(biāo)簽創(chuàng)建一個(gè)頁(yè)面。 在頁(yè)面加載事件中寫(xiě)入以下代碼:
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í),輸出為:
Page Created.
Creating test item.
Storing test item in cache for 30 seconds.
如果您在30秒內(nèi)再次單擊該按鈕,頁(yè)面將被回發(fā),但標(biāo)簽控件從緩存中獲取其信息,如下所示:
Page Posted Back.
Retrieving test item.
Test item is: 14-07-2017 22:25:34