2010-02-15 64 views
5

的代碼:爲什麼/何時會話寫入容易受線程終止影響?

Session["foo"] = "bar"; 
Response.Redirect("foo.aspx"); 

問題:

當foo.aspx讀取會話 「富」,它不存在。 會話在那裏,但「foo」沒有任何價值。

我在我們的生產環境中間歇性地觀察到這種情況。但我並不是在這裏問問a question about Response.Redirect()

的解釋:

Bertrand Le Roy解釋(在粗體是我的):

現在,重定向確實是一個 特殊的頭髮送到客戶端,以便 它要求服務器對於不同的 頁面而不是它正在等待的頁面。 服務器端,發送此 標頭後,重定向結束響應。 這是一件非常暴力的事情。 Response.End實際上使用ThreadAbortException停止 頁面的執行,無論它是否爲 。 真的發生在這裏的是 會話令牌在戰鬥中丟失

我的外賣是有Response.Redirect()可以是結束線程的霸道。如果它們出現在過於靠近的地方,那會威脅我的會話寫入。

問題:

什麼ASP.NET會話管理使得它很容易嗎? Response.Redirect()代碼行直到會話寫入行被「完成」纔開始執行 - 它怎麼會成爲會話寫入的威脅呢?

在執行下一行代碼之前會話寫入不會「完成」嗎?會話寫入是否有類似的其他情況(好像它們從未發生過)丟失?

回答

1

在測試了幾個替代方案(Response.Redirect(...,false),Server.Transfer()和其他「解決方案」我現在還不記得)之後,我們發現這個問題只有一個可靠的答案。

將我們的會話狀態從InProc移動到SqlServer有效地消除了我們系統中的這種行爲,使Response.Redirect(...)完全可靠。如果進一步的測試顯示,否則我會在這裏報告,但我說,要在您的環境中發生這種情況:將會話狀態轉移到SqlServer中(或者「InProc」不夠好?我不確定)。

2

我對會話編寫的內幕不夠熟悉,但我想它有一些複雜性,因爲它依賴於將瀏覽器會話cookie轉換爲服務器標識。另外,運行時ThreadAbortExceptions do have special considerations,可能在這裏播放,我不確定。

在任何情況下,Response.Redirect()都有一個帶有布爾參數的重載,它允許您指定是否要結束線程。

Response.Redirect(string url, bool endResponse); 

如果您endResponse設置爲「假」稱呼它,它會優雅地完成,而不是調用Thread.Abort()內部。但是,這意味着它將在完成之前執行頁面生命週期中剩下的任何代碼。

一個很好的折衷辦法是撥打Response.Redirect(url, false)後跟Application.CompleteRequest()。這將允許您的重定向發生,但也可以使用最少量的附加生命週期處理來正常關閉當前的執行上下文。

0

應用程序池回收可能會導致您的會話消失。您可以將應用程序池配置爲在固定時間(推薦,在晚上或在低使用率期間)回收,或增加應用程序池回收的超時期限。

相關問題