首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 五種數據緩存方案對比:Session、Cache、客戶端文件、Cookie、隱藏字段

     編輯:關於C#

背景:頻繁資料庫訪問導致效能瓶頸

專案運行緩慢,程式碼檢視發現大量重複、大結果集的資料庫查詢。引入緩存是首選優化手段,但緩存策略選型直接影響架構複雜度與資源消耗。本文對比五種常見方案優劣與適用場景。

方案對比總覽

方案儲存位置生命週期容量限制適用場景核心缺點
Session伺服器記憶體/StateServer/SQL/RedisSession 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 狀態保持非持久、明文可見、篡改風險、大數據傳輸慢

深度分析與代碼範例

1. Session - 用戶隔離但擴展性差


// 寫入
Session["UserReportData"] = dataset;
// 讀取
if (Session["UserReportData"] is DataSet ds) { /* 繫結報表 */ }

避坑:web.config 配置 <sessionState mode="Redis" ... /> 實現分散式,否則單機記憶體上限約 1-2GB 即 OOM。

2. Cache - 全站共享的高速緩存


// 寫入,滑動過期 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 實現資料庫變更自動失效,解決「緩存髒讀」核心痛點。

3. 客戶端文件 - 只有 IE/Edge IE 模式支援


<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 環境,不建議新專案採用。

4. Cookie - 輕量級狀態傳遞


// 寫入
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」。嚴禁存儲業務數據集。

5. 隱藏字段 / XML 字串 Post 回傳 - 頁面間臨時傳遞


// 頁面 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 下載 / 後端生成文件提供下載鏈接

現代架構建議:多級緩存

  1. L1: 進程內 MemoryCache:熱點數據、極低延遲、自動淘汰(Microsoft.Extensions.Caching.Memory)。
  2. L2: 分散式 Redis:共享數據、Session、分佈式鎖、發布訂閱失效通知。
  3. L3: 資料庫:最終一致性來源。
  4. 緩存穿透/擊穿/雪崩防護:空值緩存、互斥鎖重建、隨機過期時間。

總結

原文列舉的五種方案中,Cache (HttpRuntime.Cache) 為伺服器端通用緩存首選,Session 次之;Cookie、隱藏字段、客戶端文件均非業務數據緩存正解。現代 .NET 應遷移至 IDistributedCache 抽象 + Redis 實現,配合多級緩存架構,在一致性、可用性、效能間取得最佳平衡。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved