作者: Tomex Ou
版本歷史:
2008/09/28 PM 04:03:09 研究ASP.NET Caching心得筆記
Cache使用時機
ASP.NET的頁面快取很容易能實現,但是只要遇到更新或分頁,資料不一致的問題就會產生。我歷練實際專案的實作,也找了網路上很多資料,會建議初學者從數據快取做起,局部利用Caching來改善網站效能。頁面快取的資料同步問題很多,除非必要或互動功能少,否則盡量少用。另,快取會消耗server的記憶體容量,存取次數不頻繁的頁面,就不要作快取。以下,我僅摘錄Caching重點部分,詳細用法網路上很多,但變化萬千的僅是幾招而己。
Cache概念
HttpApplication 收到 web request 以後處理的順序:
1. BeginRequest
2. AuthenticateRequest
3. AuthorizeRequest
4. ResolveRequestCache
5. AcquireRequestState
6. PreRequestHandlerExecute
7. PostRequestHandlerExecute
8. ReleaseRequestState
9. UpdateRequestCache
10.EndRequest
頁面緩存(Page Caching)
以頁面設定:
<%@ OutputCache Duration="60" VaryByParam="None" %>
若要在*.cs中設定Cache:
// 基本指令
Response.Cache.SetExpires(DateTime.Now.AddSeceonds(10));
Response.Cache.SetCacheability(HttpCacheablility.Public);
// 設定參數
Response.Cache.SetValidUnitlExpires(true)
Response.Cache.VaryByParams"SerialId" = true;
當你使用VaryByXXX="" 來更新更面,其實它是建立不同版本的Cache頁面
這樣反而是浪費Server的記憶體,前端此頁應該只保留一份就好,再後台更新資料時,可呼叫下面函式更新某頁:
HttpResponse.RemoveOutputCacheItem(this.ResolveUrl("~/Default.aspx"));
頁面路徑必須是"絕對的虛擬路徑",即使用"/Dir1/Page.aspx",而不能使用"~/Page1.aspx或../Page1.aspx"相對路徑。
另外,也可以將頁面緩存依附在一個key值,利用數據緩存的方式Cache.Insert("Key")去更新:
// 快取頁面
<%@ OutputCache Duration="10" VaryByParam="None" %>
// *.cs裏, Page_Load()寫入Cache Key. (亦可寫在Global.asax的Application_Start())
Cache.Add("CacheKey", DateTime.Now, null, System.Web.Caching.Cache.NoAbsoluteExpiration, System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.NotRemovable, null);
Response.AddCacheItemDependency("Key"); // 若key不值在,cache會失敗,因此上面用Cache.Add()
// 移除頁面
Cache.Remove("CacheKey"); // 或用Cache.Insert()更新key亦可
快取替換(Substitution)
當某一頁面都被Cache住,只有一部分想動態更新,可以使用Substitution控制項。不過它的函式回傳值都是string,且是static函式,實用性上不是很高。
// ASPX頁面
<esc><asp:Substitution ID="Substitution1" runat="server" MethodName="GetDateTime" />
// CS
public static string GetDateTime(HttpContext context)
{
return DateTime.Now.ToString();
}
數據緩存(DataSource Caching)
Cache類的生存週期等於應用程序的生命週期。
數據緩存的代碼如下:
DataTable table = this.Cache["Key"] as DataTable;
if (table == null)
{
table = this.Database.ExecuteDataTable(cmd);
// 更新(永不過期) => 長佇會浪費Server記憶體
this.Cache.Insert("Key", table, null, DateTime.MaxValue, System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.High, null);
// 更新(上次存取後20分鐘) => 較佳
this.Cache.Insert("Key", table, null, System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(20), System.Web.Caching.CacheItemPriority.High, null);
}
Repeater1.DataSource = table;
Repeater1.DataBind();
Cache.Insert()與Cache.Add()不同之處,在於參考文獻#1文章所述,Insert()是替代既有的值,Add()雖加入新值,但新值卻在舊值過期後才會更新,因此在實性上,Insert()比Add()有用處。當然,也可以直接用Cache
"Key"=Object來替代(不過是否已有舊值),只是它不能設定Cache時效。