什麼是快取?快取技術是將經常使用的資料/資訊儲存在記憶體中的技術,以便下次需要相同的資料/資訊時,可以直接從記憶體中檢索,而不是由應用程式生成。
快取對於提高ASP.NET效能非常重要,因為頁面和控制元件是在這裡動態生成的。這對於資料相關的事務尤其重要,因為這些事務在響應時間上是昂貴的。
快取記憶體將常用資料放置在快速存取的媒體中,例如計算機的隨機存取儲存器。 ASP.NET執行時包含稱為快取的CLR物件的鍵值對映。 這駐留在應用程式中,可通過HttpContext
和System.Web.UI.Page
獲取。
在某些方面,快取類似於儲存狀態物件。 然而,在狀態物件中儲存資訊是確定性的,即可以指望儲存在那裡的資料,並且資料的快取是非確定性的。
在以下情況下資料將不可用:
可以使用索引器存取快取中的專案,並可以控制快取中物件的生存期並設定快取物件與其物理源之間的連結。
ASP.NET提供了以下不同型別的快取:
輸出快取 - 輸出快取儲存最終呈現的HTML頁面的副本或傳送到用戶端的部分頁面。 當下一個客戶請求這個頁面時,不用重新生成頁面,而是傳送頁面的快取副本,從而節省時間。
資料快取 - 資料快取意味著快取來自資料源的資料。只要快取未過期,就會從快取中滿足對資料的請求。 當快取過期時,資料源獲取新的資料,並重新填充快取。
物件快取 - 物件快取快取頁面上的物件,如資料系結控制元件。 快取的資料儲存在伺服器記憶體中。
類快取 - Web頁面或Web服務在第一次執行時會組合到程式集中的頁面類中。然後程式集被快取在伺服器中。下一次請求頁面或服務時,會參照快取的程式集。 當原始碼改變時,CLR重新編譯程式集。
組態快取 - 應用程式範圍的組態資訊儲存在組態檔案中。 組態快取將組態資訊儲存在伺服器記憶體中。
在本教學中,我們將考慮輸出快取,資料快取和物件快取。
渲染頁面可能涉及一些複雜的過程,如資料庫存取,渲染複雜的控制元件等。輸出快取允許通過快取記憶體中的資料繞過伺服器往返。即使整個頁面也可以被快取。
OutputCache
指令負責輸出快取。它啟用輸出快取並提供對其行為的一定控制。
OutputCache
指令的語法:
<%@ OutputCache Duration="15" VaryByParam="None" %>
把這個指令放在page
指令下。這告訴環境快取頁面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
秒。 但是,下次重新整理頁面時,不需要任何時間,因為頁面是從快取中檢索的而不是重新載入的。
OutputCache
指令具有以下屬性,這有助於控制輸出快取的行為:
編號 | 屬性 | 值 | 描述 |
---|---|---|---|
1 | DiskCacheable |
true/false |
指定可以將輸出寫入基於磁碟的快取。 |
2 | NoStore |
true/false |
指定是否傳送「無儲存」快取控制標題。 |
3 | CacheProfile |
字串名稱 | 要儲存在web.config 中的快取組態檔案的名稱。 |
4 | VaryByParam |
None * Param-name |
以分號分隔的字串列表指定POST 請求中或GET 請求變數中的查詢字串值。 |
5 | VaryByHeader |
*Header names |
以分號分隔的字串列表指定可能由用戶端提交的檔頭。 |
6 | VaryByCustom |
瀏覽器 自定義字串 | 告訴ASP.NET通過瀏覽器名稱和版本或自定義字串來改變輸出快取。 |
7 | Location |
Any Client Downstream Server None | Any :頁面可能被快取在任何地方。Client :快取的內容保留在瀏覽器中。Downstream :儲存在下游和伺服器中的快取內容。Server :僅在伺服器上儲存的快取內容。 |
8 | Duration |
數位 | 頁面或控制元件被快取的秒數。 |
新增一個文字框和一個按鈕到前面的例子,並新增這個按鈕的事件處理程式。
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" %>
程式執行時,ASP.NET會根據文字框中的名稱來快取頁面。
資料快取的主要方面是快取資料源控制元件。 我們已經討論過,資料源控制元件代表資料源中的資料,如資料庫或XML檔案。這些控制元件派生自抽象類DataSourceControl
,並具有以下用於實現快取的繼承屬性:
為了演示資料快取,建立一個新的網站並在其上新增一個新的Web表單。 使用資料存取教學中已經使用的資料庫連線新增一個SqlDataSource
控制元件。
對於這個例子,新增一個標籤到頁面,這將顯示頁面的響應時間。
<asp:Label ID="lbltime" runat="server"></asp:Label>
內容頁面除了標籤之外,與資料存取教學中的內容頁面相同。 為頁面載入事件新增一個事件處理程式:
protected void Page_Load(object sender, EventArgs e)
{
lbltime.Text = String.Format("Page posted at: {0}", DateTime.Now.ToLongTimeString());
}
設計好的頁面應該如下所示:
當您第一次執行頁面時,沒有什麼不同,標籤顯示,每次重新整理頁面時,頁面都會重新載入,並且標籤上顯示的時間會發生變化。
接下來,將資料源控制元件的EnableCaching
屬性設定為true
,並將Cacheduration
屬性設定為60
。 它將實現快取,快取將每60秒過期。
每次重新整理都會更改時間戳,但如果在60秒內更改了表中的資料,則在快取過期之前不會顯示該資料。
參考以下程式碼 -
<asp:SqlDataSource ID = "SqlDataSource1" runat = "server"
ConnectionString = "<%$ ConnectionStrings: ASPDotNetStepByStepConnectionString %>"
ProviderName = "<%$ ConnectionStrings: ASPDotNetStepByStepConnectionString.ProviderName %>"
SelectCommand = "SELECT * FROM [DotNetReferences]"
EnableCaching = "true" CacheDuration = "60">
</asp:SqlDataSource>
物件快取比其他快取技術提供更多的靈活性。 可以使用物件快取將任何物件放置在快取中。 該物件可以是任何型別 - 資料型別,Web控制元件,類,資料集物件等。只需通過分配新的鍵名稱即可將該項新增到快取中,如下所示:
Cache["key"] = item;
ASP.NET還提供了將物件插入快取的Insert()
方法。 此方法有四個過載版本。如下所列 -
編號 | 方法 | 描述 |
---|---|---|
1 | Cache.Insert((key, value); |
使用鍵名稱和值將專案插入快取記憶體,預設優先順序和到期。 |
2 | Cache.Insert(key, value, dependencies); |
將專案插入快取記憶體中,其中包含鍵值,預設優先順序,到期時間以及連結到其他檔案或專案的CacheDependency 名稱,以便在更改快取專案時不再有效。 |
3 | Cache.Insert(key, value, dependencies, absoluteExpiration, slidingExpiration); |
這表明與上述問題一起的到期策略。 |
4 | Cache.Insert(key, value, dependencies, absoluteExpiration, slidingExpiration, priority, onRemoveCallback); |
這個引數和引數也允許設定快取專案的優先順序和一個委託,指向一個方法被呼叫時,該專案被刪除。 |
滑動到期用於在指定的時間間隔內未使用時從快取中刪除專案。 以下程式碼片段儲存滑動過期時間為10
分鐘,不具有依賴性。
Cache.Insert("my_item", obj, null, DateTime.MaxValue, TimeSpan.FromMinutes(10));
用一個按鈕和一個標籤建立一個頁面。 在頁面載入事件中寫入以下程式碼:
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-2017 22:25:34