一、會話狀態Session
Session用於服務器端狀態管理,使用Session之后,每個客戶端都可以將實際的數據保存在服務器上,對於每個客戶端的數據,將會生成一個對應的唯一的key(保存在客戶端)。客戶端與服務器端就是通過這個key來確認客戶端的身份,通常這個key為SessionID。
一般情況下,SessionID以Cookie的形式保存在瀏覽器中,在不使用Cookie的情況下,也可以將這個SessionID嵌入到訪問網頁的URL中。
二、服務器端Session
在頁面對象或者HttpContext對象中,都有一個名為Session的屬性,在一次會話中,它們引用的都是同一個對象。
Session對象是HttpSessionState類的實例。Session是保存在服務器端的,對每個登錄到網站的用戶都有一份,是獨有的,而其他用戶無法共享。
HttpSessionState來自於HttpModule的SessionStateModule。在每次請求處理過程中,HttpApplication的請求的處理管道中會檢查當前請求的處理程序是否實現了接口IRequiresSessionState,如果實現的話,那么SessionStateModule將為這個請求分配HttpSessionState。同時SessionStateModule還負責SessionID的生成、Cookieless會話管理、從外部狀態提供程序中檢索會話數據以及將數據綁定到請求的調用上下文。
- 對於一般處理程序,默認情況下沒有實現IRequiresSessionState接口。所以如果想要在一般處理程序中使用Session,可以通過實現IRequiresSessionState接口來解決這個問題,這個接口是一個標記接口,並沒有定義任何內容。
- 對於頁面處理程序,可以將頁面指令@Page的EnableSessionState屬性設置為true,以允許頁面可以請求會話狀態的寫入權限。這是默認的設置。還可以將EnableSessionState屬性設置為ReadOnly,此時派生的實際頁面類將會實現接口IReadOnlySessionState,在這種情況下,頁面可以擁有會話狀態的只讀權限。
SessionStateModule模塊從特定狀態提供程序中讀取數據。在程序代碼中實際上訪問的是會話數據在本地內存中的副本,如果其他頁面也視圖同步訪問該會話狀態就可能會導致數據沖突。為了避免這種情況,SessionStateModule模塊實現了一個讀取器/寫入器的鎖定機制,並對狀態值的訪問進行排隊。對會話狀態具有寫入權限的頁面將保留該會話的寫入器鎖定,直到請求終止。
如果頁面請求設置一個讀取器鎖定,同一會話中同時處理的其他請求將無法更新會話狀態,但是至少可以進行讀取。如果頁面請求為會話狀態設置一個寫入鎖,那么所有其他頁面都被阻止,無論他們是否要讀取或寫入內容。例如,如果同時有兩段程序視圖在同一個Session中寫入內容,一段程序必須等到另一段程序完成后才能寫入。在AJAX程序設計中,必須注意這種情況的發生。
網上查了一下 基本上的解決方案 如下
對於Asp.net MVC:
可以為本Controller增加以下特性,但是本Controller都不能修改Session了,只能讀取
[SessionState(System.Web.SessionState.SessionStateBehavior.ReadOnly)]
對於Asp.net WebForm:
在Web.config 文件里面添加EnableSessionState="ReadOnly" // 僅僅加載那個阻塞頁面
經過測試上面的方法並未有卵用 已將session 改為 System.Web.Caching.Cach 或者 Redis 或者 memcached來實現
大概實現邏輯就是 自己生成一個key 這個key可以是用戶Id 然后 通過cookie的方式寫到客戶端 每次客戶端訪問服務器都攜帶這個cooike 就可以實現自己的會話變量了
其主要目的是為個規避session鎖的問題 尤其是頁面使用了進度條的 .... 特此筆記記錄