快取 是 ASP.NET 提升應用程式效能的核心技術。透過將耗時運算結果、資料庫查詢資料、頁面輸出 HTML 存放在記憶體中,後續請求可直接從快取讀取,大幅降低回應延遲與資料庫負載。本文系統整理輸出快取、資料快取、快取相依性、回呼與最佳實務。
<%@ OutputCache Duration="60" VaryByParam="None" %>
Duration="60":快取 60 秒VaryByParam="None":不依查詢字串區分,單一快取副本<%@ OutputCache Duration="60" VaryByParam="*" %>
<%@ OutputCache Duration="60" VaryByParam="id;category" %>
<%@ OutputCache Duration="60" VaryByCustom="browser" %>
Global.asax 實作:
public override string GetVaryByCustomString(HttpContext context, string custom)
{
if (custom == "browser")
return context.Request.Browser.Browser + context.Request.Browser.MajorVersion;
return base.GetVaryByCustomString(context, custom);
}
<%@ Control Language="C#" %>
<%@ OutputCache Duration="120" VaryByControl="CategoryDropDownList" %>
<%@ OutputCache Duration="120" VaryByParam="None" Shared="true" %>
<!-- Web.config -->
<system.web>
<caching>
<outputCacheSettings>
<outputCacheProfiles>
<add name="LongCache" duration="3600" varyByParam="*" />
<add name="ShortCache" duration="60" varyByParam="none" />
</outputCacheProfiles>
</outputCacheSettings>
</caching>
</system.web>
<!-- 頁面使用 -->
<%@ OutputCache CacheProfile="LongCache" %>
// 簡單寫入/讀取
Cache["Key"] = data;
var data = Cache["Key"] as MyType;
// 進階 Insert - 支援過期、優先序、相依性
Cache.Insert("Key", data,
dependencies: null,
absoluteExpiration: DateTime.Now.AddMinutes(10),
slidingExpiration: TimeSpan.Zero,
priority: CacheItemPriority.Normal,
onRemoveCallback: null);
| 策略 | 語法 | 行為 |
|---|---|---|
| 絕對過期 | DateTime.Now.AddMinutes(10) | 固定時間點過期 |
| 滑動過期 | TimeSpan.FromMinutes(5) | 閒置 5 分鐘過期(每次存取重設) |
| 永不過期 | Cache.NoAbsoluteExpiration + TimeSpan.Zero | 依記憶體壓力淘汰 |
注意: 絕對過期與滑動過期不可同時使用。
// 檔案相依性:檔案異動自動失效
var dep = new CacheDependency(Server.MapPath("~/Data/config.xml"));
Cache.Insert("ConfigData", configData, dep);
// 快取鍵相依性:另一快取項過期時連帶失效
string[] keys = { "MasterData" };
var keyDep = new CacheDependency(null, keys);
Cache.Insert("DetailData", detailData, keyDep);
// 多重相依性
var aggregateDep = new AggregateCacheDependency();
aggregateDep.Add(fileDep);
aggregateDep.Add(keyDep);
Cache.Insert("Combined", data, aggregateDep);
CacheItemRemovedCallback callback = (key, value, reason) =>
{
// 記錄移除原因:Expired, Removed, Underused, DependencyChanged
Log($"Cache removed: {key}, Reason: {reason}");
// 可在此重新載入資料(但注意:快取已移除,使用者可能等待)
};
Cache.Insert("Key", data, null,
DateTime.Now.AddMinutes(10), TimeSpan.Zero,
CacheItemPriority.High, callback);
public DataTable GetCustomers(bool bypassCache = false)
{
const string cacheKey = "CustomersDataTable";
// 1. 嘗試從快取取得
if (!bypassCache && Cache[cacheKey] is DataTable cached)
return cached;
// 2. 快取未命中或旁路 → 從資料源載入
var data = LoadCustomersFromDatabase();
// 3. 存入快取(設定過期與相依性)
Cache.Insert(cacheKey, data,
new CacheDependency(Server.MapPath("~/App_Data/Customers.xml")),
DateTime.Now.AddMinutes(30), TimeSpan.Zero);
return data;
}
as 或模式比對| 原則 | 說明 |
|---|---|
| 儘早快取、經常快取 | 各層(資料、業務、UI、輸出)皆實作快取 |
| 快取可掩蓋效能缺失 | 30 秒快取勝過一週優化,但不應掩蓋架構缺陷 |
| 頁面級輸出快取最簡單 | 一行指令即可,效能提升明顯 |
| 片段快取重用率高 | UserControl + Shared="true" 跨頁共用 |
| 資料快取最靈活 | 支援相依性、回呼、優先序、自訂淘汰 |
| 快取鍵命名規範 | 建議:Layer_Entity_Context 如 DAL_Customer_List |
| 監控快取命中率 | 效能計數器:ASP.NET Applications > Cache Total Hit Ratio |
| 避免快取大型物件圖 | 序列化/反序列化開銷、記憶體碎片 |
| 測試快取失效情境 | 確保資料一致性、避免臟讀 |
Server.MapPath 確保絕對路徑ASP.NET 快取系統提供從簡單的頁面輸出快取到複雜的資料快取相依性網路,完整的效能優化工具箱。掌握 OutputCache 指令參數、Cache.Insert 進階選項、相依性鏈結設計與標準存取模式,能系統性地解決效能瓶頸。記住:快取是效能加速器,不是架構止痛藥——在享受快取帶來的效能紅利時,仍需持續優化資料庫查詢、演算法複雜度與架構設計。