核心差異速查表
| 維度 | Session | Cache (System.Web.Caching) |
| 儲存範圍 | 單一使用者會話 | 整個應用程式域 |
| 生命週期 | 會話結束或逾時 (預設 20 分鐘) | 依設定:絕對過期、滑動過期、相依性觸發 |
| 資料隔離 | 使用者間完全隔離 | 全域共享,需自行管理鍵名空間 |
| 容量建議 | 輕量資料 (用戶偏好、購物車、權限) | 大量資料 (資料表快取、計算結果、頁面片段) |
| 序列化需求 | Out-of-process 模式需可序列化 | 同進程無需,分散式需序列化 |
| 回收機制 | 逾時自動移除 | 記憶體壓力主動淘汰 (LRU)、過期、檔案/快取相依性 |
| 分散式支援 | State Server / SQL Server / Redis | 需自行實作或用 Redis / NCache 等 |
Session 深度解析
儲存模式 (web.config)
常見誤區
- Session 變數未初始化即讀取:永遠用
Session["key"] as Type 或 Session["key"] ?? defaultValue。
- 存放大型物件:導致記憶體暴增、序列化/反序列化延遲。改用 Cache 或資料庫。
- 依賴 Session 進行關鍵業務邏輯:使用者關閉瀏覽器、清除 Cookie、換裝置即失效。關鍵狀態應持久化至資料庫。
Cache 深度解析
核心 API
// 插入/更新 (滑動過期 20 分鐘)
Cache.Insert("Key", value, null, Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(20));
// 插入 (絕對過期 1 小時)
Cache.Insert("Key", value, null, DateTime.Now.AddHours(1), Cache.NoSlidingExpiration);
// 插入 (檔案相依性:檔案變更自動失效)
Cache.Insert("Key", value, new CacheDependency(Server.MapPath("~/Config.xml")));
// 取得 (安全模式)
object val = Cache["Key"]; // 可能為 null
// 移除
Cache.Remove("Key");
// 回呼通知 (項目被移除時)
Cache.Insert("Key", value, null, DateTime.Now.AddMinutes(10), Cache.NoSlidingExpiration,
CacheItemPriority.Normal, (key, value, reason) => {
// 記錄日誌、重新載入等
});
Cache 相依性類型
CacheDependency:檔案/目錄變更。
AggregateCacheDependency:多重相依性 (任一觸發即失效)。
SqlCacheDependency (SQL Server 2005+):資料表變更通知 (需啟用 Service Broker)。
實戰選型決策樹
需要跨使用者共享資料?
├─ 否 → 資料量小且隨會話生命週期? → Session
│ └─ 資料量大或需持久化? → 資料庫 / Cache (Key 含 UserId)
└─ 是 → 資料常變動且需即時性? → 直接查詢 DB / SignalR 推播
└─ 資料較穩定、讀多寫少? → Cache + 相依性/過期策略
效能壓測參考 (單機 IIS, 4C8G)
| 操作 | InProc Session | Redis Session | In-Memory Cache |
| 寫入 1KB 物件 | 0.05 ms | 1.2 ms | 0.03 ms |
| 讀取 1KB 物件 | 0.02 ms | 0.8 ms | 0.01 ms |
| 10萬筆並發讀寫 | CPU 瓶頸 | 網路/序列化瓶頸 | 記憶體/GC 瓶頸 |
現代架構建議 (ASP.NET Core / 分散式系統)
- Session:僅存
UserId、CsrfToken、Preferences 等極小資料,後端用 **Redis** (IDistributedCache)。
- Cache:
• 本機記憶體:IMemoryCache (單機、熱資料)。
• 分散式:IDistributedCache (Redis、SQL Server) — 多實例共享。
• 回應快取:ResponseCache / OutputCache (MVC/Razor Pages)。
- 避免:在 Session/Cache 存放實體領域模型、DbContext、大型集合、未序列化物件。
遷移檢查清單 (舊 ASP.NET → Core)
- 將
HttpContext.Session 替換為 ISession (擴充方法 GetString/SetString)。
Cache → IMemoryCache / IDistributedCache (介面注入)。
- 移除
web.config sessionState 區段,改用 services.AddSession() + services.AddDistributedRedisCache()。
- 檢查所有序列化類別標記
[Serializable] 或改用 JSON 序列化 (System.Text.Json)。