我剛剛發現了為什麼所有 ASP.Net 網站都很慢,我正在嘗試解決這個問題
我剛剛發現 ASP.Net Web 應用程序中的每個請求在請求開始時都會獲得一個會話鎖,然後在請求結束時釋放它!
萬一這對你的影響,就像一開始對我一樣,這基本上意味著以下內容:
- 任何時候 ASP.Net 網頁需要很長時間才能載入(可能是由於數據庫呼叫緩慢或其他原因),並且使用者決定他們想要導航到不同的頁面,因為他們厭倦了等待,他們不能!ASP.Net 會話鎖強制新頁面請求等待,直到原始請求完成其令人痛苦的緩慢載入。啊。
- 每當 UpdatePanel 載入緩慢時,使用者決定在 UpdatePanel 完成更新之前導航到不同的頁面……他們不能!ASP.net 會話鎖強制新頁面請求等待原始請求完成其令人痛苦的緩慢載入。雙Arrrgh!
那麼有哪些選擇呢?到目前為止,我想出了:
- 實現 ASP.Net 支持的自定義 SessionStateDataStore。我沒有找到太多可以複製的東西,而且看起來風險很高,而且很容易搞砸。
- 跟踪所有正在進行的請求,如果請求來自同一使用者,則取消原始請求。似乎有點極端,但它會起作用(我認為)。
- 不要使用會話!當我需要使用者的某種狀態時,我可以只使用記憶體,並在經過身份驗證的使用者名上使用關鍵項,或者類似的東西。再次顯得有些極端。
我真的不敢相信 ASP.Net 微軟團隊會在 4.0 版本的框架中留下如此巨大的性能瓶頸!我錯過了一些明顯的東西嗎?為 Session 使用 ThreadSafe 集合有多難?
好的,對 Joel Muller 的所有投入都給予了極大的支持。我的最終解決方案是使用這篇 MSDN 文章末尾詳述的自定義 SessionStateModule:
<http://msdn.microsoft.com/en-us/library/system.web.sessionstate.sessionstateutility.aspx>
這是:
- 實施起來非常快(實際上似乎比使用提供者路線更容易)
- 使用了很多開箱即用的標準 ASP.Net 會話處理(通過 SessionStateUtility 類)
這對我們的應用程序“敏捷”的感覺產生了巨大的影響。我仍然無法相信 ASP.Net Session 的自定義實現會鎖定整個請求的會話。這給網站增加瞭如此多的遲緩。從我必須做的大量線上研究(以及與幾位非常有經驗的 ASP.Net 開發人員的對話)來看,很多人都遇到過這個問題,但很少有人能找到原因。也許我會寫一封信給Scott Gu…
我希望這可以幫助一些人!
如果您的頁面沒有修改任何會話變數,您可以選擇退出大部分鎖定。
<% @Page EnableSessionState="ReadOnly" %>如果您的頁面沒有讀取任何會話變數,您可以為該頁面選擇完全退出此鎖定。
<% @Page EnableSessionState="False" %>如果您的頁面都沒有使用會話變數,只需在 web.config 中關閉會話狀態。
<sessionState mode="Off" />我很好奇,如果“ThreadSafe 集合”不使用鎖,你認為它會如何成為執行緒安全的?
編輯:我可能應該用“選擇退出大部分鎖定”來解釋我的意思。可以為給定會話同時處理任意數量的只讀會話或非會話頁面,而不會相互阻塞。但是,讀寫會話頁面在所有隻讀請求完成之前無法開始處理,並且在執行時它必須具有對該使用者會話的獨占訪問權限以保持一致性。鎖定單個值是行不通的,因為如果一個頁面將一組相關值作為一個組更改怎麼辦?您將如何確保同時執行的其他頁面能夠獲得使用者會話變數的一致視圖?
如果可能,我建議您在設置會話變數後儘量減少對它們的修改。這將允許您將大部分頁面設置為只讀會話頁面,從而增加來自同一使用者的多個同時請求不會相互阻塞的機會。