專案運行緩慢,程式碼檢視發現大量重複、大結果集的資料庫查詢。引入緩存是首選優化手段,但緩存策略選型直接影響架構複雜度與資源消耗。本文對比五種常見方案優劣與適用場景。
| 方案 | 儲存位置 | 生命週期 | 容量限制 | 適用場景 | 核心缺點 |
|---|---|---|---|---|---|
| Session | 伺服器記憶體/StateServer/SQL/Redis | Session Timeout (預設 20 分鐘) | 受伺服器記憶體限制 | 用戶私有、會話級數據(購物車、權限) | 用戶量大時記憶體暴增,需分散式 Session |
| Cache (HttpRuntime.Cache) | 伺服器記憶體 | 絕對/滑動過期、依賴項觸發 | 受伺服器記憶體限制,可設上限淘汰 | 全站共享、讀多寫少、可容忍短暫不一致的數據(字典表、配置、報表) | 進程內,單機部署;Web Farm 需分散式緩存 |
| 客戶端文件 | 用戶磁碟 (ActiveX/FSObject) | 手動刪除前永久 | 受磁碟配額、瀏覽器安全策略限制 | 離線報表、大數據集本地打印預覽 | 需 ActiveX 權限、跨瀏覽器相容性差、安全風險高 |
| Cookie | 用戶瀏覽器 | Expires/Max-Age | 單 Cookie 4KB,單域 20-50 個,總 300 個 | 極少量狀態標識(Token、偏好設定、追蹤 ID) | 容量極小、每請求自動攜帶增大頻寬、不安全 |
| 隱藏字段 / ViewState | 頁面 HTML | 單次請求週期 | 受頁面大小限制,過大影響傳輸 | 頁面間小數據傳遞、GridView 狀態保持 | 非持久、明文可見、篡改風險、大數據傳輸慢 |
// 寫入
Session["UserReportData"] = dataset;
// 讀取
if (Session["UserReportData"] is DataSet ds) { /* 繫結報表 */ }
避坑:web.config 配置 <sessionState mode="Redis" ... /> 實現分散式,否則單機記憶體上限約 1-2GB 即 OOM。
// 寫入,滑動過期 30 分鐘,依賴 SQL 表變更自動失效
Cache.Insert("ProductCatalog", catalog, new SqlCacheDependency("connStr", "Products"),
Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(30), CacheItemPriority.Normal, null);
// 讀取
if (Cache["ProductCatalog"] is List list) { /* 使用 */ }
關鍵:SqlCacheDependency 或 HttpCachePolicy 實現資料庫變更自動失效,解決「緩存髒讀」核心痛點。
<script>
function saveReportXml(xmlStr) {
var fso = new ActiveXObject("Scripting.FileSystemObject");
var file = fso.CreateTextFile("C:\\Reports\\report.xml", true);
file.Write(xmlStr);
file.Close();
}
</script>
現狀:現代瀏覽器均封殺 ActiveX,僅限內網 IE 環境,不建議新專案採用。
// 寫入
var cookie = new HttpCookie("UserPref", "theme=dark&lang=zh-TW") { Expires = DateTime.Now.AddDays(30) };
Response.Cookies.Add(cookie);
// 讀取
if (Request.Cookies["UserPref"] is HttpCookie c) { /* 解析 */ }
實測限制:單值超過 4KB 瀏覽器拒絕,總大小超限導致「Bad Request - Request Too Long」。嚴禁存儲業務數據集。
// 頁面 A 生成
string xml = dataset.GetXml();
hidXml.Value = xml; // <input type="hidden" id="hidXml" runat="server" />
// 頁面 B 接收
string xml = Request.Form["hidXml"];
var ds = new DataSet();
ds.ReadXml(new StringReader(xml));
編碼坑:頁面指令加 `<%@ Page ResponseEncoding="gb2312" %>` 或統一 UTF-8,否則中文亂碼。
需要跨用戶共享?
├─ 是 → 數據更新頻率低、容忍秒級不一致?
│ ├─ 是 → HttpRuntime.Cache / Redis / MemoryCache (推薦)
│ └─ 否 → 直接查庫或讀寫分離 + 本地緩存
└─ 否 → 用戶私有數據?
├─ 會話級、中小數據 → Session (分散式)
├─ 持久化偏好設定 → Cookie (極小) / LocalStorage (前端)
└─ 大數據離線導出 → 前端 Blob 下載 / 後端生成文件提供下載鏈接
Microsoft.Extensions.Caching.Memory)。原文列舉的五種方案中,Cache (HttpRuntime.Cache) 為伺服器端通用緩存首選,Session 次之;Cookie、隱藏字段、客戶端文件均非業務數據緩存正解。現代 .NET 應遷移至 IDistributedCache 抽象 + Redis 實現,配合多級緩存架構,在一致性、可用性、效能間取得最佳平衡。