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

ASP.NET Session 七大核心認知深度解析

     編輯:ASP.NET 基礎

前言

Session 是 ASP.NET 狀態管理的基石,但許多開發者僅停留在「存取值」層面。本文從值/引用類型行為、生命周期、Web Service 調用、過期機制、序列化要求、內存釋放、SessionID 行為七個維度,深度剖析 Session 內部機制,助你避開生產環境坑點。

一、值類型存儲的是副本

Session["count"] = 1;
int i = (int)Session["count"] + 1; // i = 2
int j = (int)Session["count"];     // j = 1 (原值不變)

本質:值類型在 Session 中經過裝箱存儲,讀取時拆箱產生新副本。修改局部變量不影響 Session 內原值。

二、引用類型存儲的是引用

DataSet ds1 = (DataSet)Session["data"];
DataSet ds2 = (DataSet)Session["data"];
ds1.Tables[0].Rows[0][0] = "999";
// ds2 同樣變為 "999",因指向同一堆對象

陷阱:多頁面共享同一 DataSet 時,一處修改波及全局。需用 ds.Copy() 創建副本隔離。

三、Session 生命周期與瀏覽器窗口關係

  • 新瀏覽器窗口(非 Ctrl+N 複製)啟動 → 新 Session → 觸發 Session_Start
  • 從現有窗口打開鏈接(target=_blank、window.open) → 共享同一 SessionID
  • Session 過期後再提交 → 新 Session → 再次觸發 Session_Start

四、Web Service 多調用共享 Session

每次調用 Web Service 默認創建新 Session。解決方案:

// 客戶端代理類設置共享 CookieContainer
CookieContainer sharedCookie = new CookieContainer();
Service1 proxy1 = new Service1 { CookieContainer = sharedCookie };
Service1 proxy2 = new Service1 { CookieContainer = sharedCookie };
// 兩個代理實例共享同一 Session

生產環境建議用單例模式管理 CookieContainer。

五、Session 數據整體過期,非單項失效

  • 默認 20 分鐘無請求活動 → 整個 Session 失效
  • 任何請求(含郵回、AJAX)均會重置滑動過期窗口
  • 無法單獨設置某個 Key 的過期時間

六、非序列化類型無法使用 SQLServer/StateServer 模式

DataView、未標記 [Serializable] 的自定義類無法在 Out-of-Process 模式下存儲。檢查方法:

// 編譯時檢查
[Serializable]
public class MyClass { }

// 運行時檢查
bool canSerialize = typeof(MyClass).IsSerializable;

七、Session 內存釋放與 Session_End 執行條件

內存不釋放現象

調用 Session.Clear() 或 Session.Abandon() 後,aspnet_wp.exe/w3wp.exe 內存不一定立即下降,因 .NET GC 非確定性回收。大對象(如 DataSet)建議顯式置 null 並調用 GC.Collect()(慎用)。

Session_End 只有在 InProc 模式下才觸發

兩個必要條件(合為充分條件):

  1. 至少完成一次完整請求(Request 執行完畢)
  2. Session 字典中寫入過數據(或定義了 Session_Start)
// Global.asax 陷阱:定義空 Session_Start 會導致 SessionID 固定,掩蓋真實問題
void Session_Start(object sender, EventArgs e) { } // 若無實際邏輯,請刪除!

實戰避坑清單

現象根因對策
SessionID 每請求變化未寫入 Session 數據Page_Load 中寫入任意值:Session["init"]=1
Session_End 不執行非 InProc 模式 / 未滿足兩條件確認模式、確保有完整請求且寫入數據
Web Service 每次新 Session無共享 CookieContainer單例管理 CookieContainer
SQLServer 模式報錯存儲非序列化對象標記 [Serializable] 或轉存可序列化 DTO

總結

Session 看似簡單,實則涉及 HTTP 無狀態協議、進程模型、序列化、GC 等核心機制。理解這七大認知,能從根源上解決「Session 丟失、內存洩漏、Web Service 狀態不同步」等棘手問題,編寫更健壯的 Web 應用。

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