註:該問題已解決,詳見終於解決“百年一遇”奇怪問題。
問題原因
經過昨天一天的奮戰,終於在吃晚飯前找到了"百年一遇"奇怪問題的原因。(問題詳情見前一篇博文:百年一遇的奇怪問題:當IE遇上.NET Framework 4.5)
問題原因是:當伺服器安裝了 .NET Framework 4.5 之後,在IE中,如果 ASP.NET MVC 處理的 ajax 請求未執行完成時,串連被中斷(比如F5重新整理瀏覽器),接下來的請求就會被卡住。
問題驗證
用 IE 訪問快閃記憶體(http://home.cnblogs.com/ing/),按 F12 開啟開發人員工具,等所有 ajax 請求執行完成再重新整理瀏覽器,問題就不會出現。
我們在測試環境中,取消所有 ajax 請求,問題就不會出現。
問題分析
為什麼 ajax 請求被中斷後會出現這個問題?
我的猜測是:ajax 請求被中斷後,伺服器端 ASP.NET Runtime 處理該請求的線程繼續保留著(可能在重新整理時, IE 繼續保持著串連),接下來的請求繼續由這個線程處理,於是卡住。所以,重啟 IE 問題會消失就是因為這時 IE 發起了新的串連,伺服器端用新的線程進行處理,這同時也解釋了第一次請求總是不會出現問題。
下面針對前一篇博文中問題的五個奇怪之處逐一進行分析:
1、“問題奇怪之一:伺服器是微軟的 ASP.NET 環境,出問題的不是其他瀏覽器,而是微軟自己的 IE 瀏覽器。”
猜測:在重新整理時,IE 可能與其他瀏覽器的處理方式不一樣,IE 會繼續保持著同一個 HTTP 串連。伺服器端 ASP.NET Runtime 對這個串連使用之前為之服務的一個線程處理(可能是 .NET Framework 4.5 的一個改變)。
2、“問題奇怪之二:IE 第一次請求不會出現問題,問題只出現在後續請求中。”
因為問題只會在 ajax 請求被中斷後的請求中出現。
3、“問題奇怪之三:同一台伺服器,有多個網站,只有這一個網站會出現這個問題。同一個網站(home.cnblogs.com),只有首頁與快閃記憶體相關頁面會出現這個問題。”
出現問題的頁有個特徵 —— ajax 請求特別多,問題可能與 ajax 請求的數量有關。
4、“問題奇怪之四:WebForms 與 MVC 都會出現這個問題。”
問題在伺服器端 ASP.NET Runtime 處理該請求的線程,所以與是 WebForms 還是 MVC 無關。
5、“問題奇怪之五:在 Global.asax 中取消所有 MVC 的路由註冊(routes.MapRoute),問題就消失。”
由於 ajax 請求是由 MVC 處理的,取消 MVC 的路由註冊也就不存在 ajax 請求被中斷的情況。
繼續奮戰
進一步的原因以及解決方案還要繼續努力研究。。。
最新進展
將 ajax 請求的處理由 MVC 改為 Web Service(.asmx) 之後,問題不再出現。由此可見,與瀏覽器、與 js 一點關係沒有。