ASP.NET Cache 物件提供伺服器端資料快取,核心挑戰在於:**何時讓快取失效,重新從資料來源載入?** 本文詳細解析三種內建失效策略:檔案依賴、絕對過期、滑動過期,並提供實戰程式碼與選型建議。
// 完整簽名
public void Insert(
string key, // 快取鍵
object value, // 快取物件
CacheDependency dependencies, // 依賴關係 (檔案、鍵、聚合)
DateTime absoluteExpiration, // 絕對過期時間
TimeSpan slidingExpiration, // 滑動過期間隔
CacheItemPriority priority, // 優先級 (記憶體壓力下淘汰順序)
CacheItemRemovedCallback onRemoveCallback // 移除回呼
);
web.config、appSettings.json、XML、JSON)protected void Page_Load(object sender, EventArgs e) {
if (!IsPostBack) {
if (Cache["news"] == null) {
DataTable dt = LoadData();
// 關鍵:建立檔案依賴
// 當 d:\cache.txt 任何變更 (修改時間、大小、刪除),快取立即失效
CacheDependency dep = new CacheDependency(@"d:\cache.txt");
Cache.Insert("news", dt, dep); // 無時間限制,純依賴驅動
// 等價: Cache.Insert("news", dt, dep, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration);
GridView1.DataSource = dt;
GridView1.DataBind();
} else {
GridView1.DataSource = (DataTable)Cache["news"];
GridView1.DataBind();
}
}
}
LastWriteTime (預設 20 秒間隔,可透過 pollTime 設定)Cache["news"] == null → 重新載入// 20 秒後絕對過期
Cache.Insert("news", dt, null,
DateTime.Now.AddSeconds(20), // absoluteExpiration
Cache.NoSlidingExpiration); // slidingExpiration = TimeSpan.Zero
// 或指定具體時間點 (如每天凌晨 3 點)
Cache.Insert("daily_report", report, null,
DateTime.Today.AddDays(1).AddHours(3), // 明天 03:00
Cache.NoSlidingExpiration);
// 30 秒內未被存取則過期
Cache.Insert("news", dt, null,
Cache.NoAbsoluteExpiration, // absoluteExpiration = DateTime.MaxValue
TimeSpan.FromSeconds(30)); // slidingExpiration
// 每次存取 (Cache["news"]) 都會重置 30 秒計時器
Cache["key"])、**寫入** (Cache["key"] = val)、**Insert** 都會重置滑動計時器| 維度 | 檔案依賴 | 絕對過期 | 滑動過期 |
|---|---|---|---|
| 觸發條件 | 外部檔案變更 | 固定時間點到達 | 閒置時間超過間隔 |
| 時間可預測性 | 不可預測 (視檔案寫入) | 完全可控 | 視存取模式動態 |
| 資料新鮮度 | 極高 (檔案改即更新) | 固定窗口內可能過舊 | 熱資料新、冷資料舊 |
| 記憶體效率 | 視檔案變更頻率 | 固定佔用至過期 | 優 (冷資料自動釋放) |
| 典型用途 | 設定檔、外部資料源同步 | 定時刷新報表、每日快照 | Session、熱門查詢結果 |
// 程式碼中使用 (需資料表啟用通知: aspnet_regsql -et -E -d DB -t Table)
CacheDependency sqlDep = new SqlCacheDependency("sqldependency", "TableName");
Cache.Insert("data", dt, sqlDep);
Module:Entity:Id:Version (如 News:List:2024:v3),便於群組清除。var dt = Cache["key"] as DataTable; if (dt == null) { reload; }Cache.Insert(..., onRemoveCallback: (k,v,r) => Log.Info($"Cache removed: {k}, reason: {r}"));CacheItemPriority 淘汰行為。Cache 不支援跨節點同步。理解三者機制與適用場景,能讓你在「資料新鮮度」與「系統效能」之間找到最佳平衡點。