天天看點

Asp.net 4.0,首次請求目錄下的檔案時響應很慢

1. 問題起因

2. 嘗試過的處理思路

3. 解決方法

    一個從VS2003(.Net Framework 1.1)更新到.net framework 4.0的項目,每次編譯或者部署到伺服器上後,首次請求任何一個目錄下的預設頁面時,都要耗時3~5秒;而以前使用.net framework 1.1的時候,沒有這個問題。

我在頁面上開啟Trace="true"來跟蹤,發現頁面的處理時間并不久(IIS重新開機,首次打開頁面時截獲的資訊):

Asp.net 4.0,首次請求目錄下的檔案時響應很慢

  但是IIS日志中,顯示首次請求頁面的耗時接近4.635秒。後續連續重新整理頁面,處理時間比較正常。。

Asp.net 4.0,首次請求目錄下的檔案時響應很慢

雖然耗時比較久,但頁面能夠打開;然後我重新開機IIS,再次打開站點,用VS附加W3WP.exe來進行調試,再次打開這個頁面的時候,發現抛出異常了:發生了 System.ArgumentException, Message=已存在具有相同鍵的條目。

    我Attach到w3wp上去後,首次通路目錄下的預設頁面,catch到ArgumentException異常,然後根據異常資訊,追蹤到 TemplateParser.ParseFile -> ParseString -> ParseStringInternal -> ProcessBeginTag;然後我就嘗試了下列努力:

1. 該目錄下預設檔案的<%@Page ....%>定義,屬性與其他檔案并沒有任何不同(除了CodeBehind和Inherits的值),我把頁面裡面的内容一點兒一點兒删掉,最後是剩下空内容(隻剩下head、body、form幾個元素)、空背景代碼,問題還依舊存在。

2. 我在這個目錄下面,建立了一個頁面(VS2010自動生成的,沒有添加任何元素或标簽),然後把這個新檔案作為該目錄預設頁,發現問題還是存在。

3. 在第2步的基礎上,打開新預設頁後,我在URL中直接輸入舊的預設頁,頁面瞬間刷出來了。然後我就糾結了,這延時,與頁面内容毛的關系都木有,這異常資訊也太坑爹了。

4. 出于嘗試一下,我試下該目錄下的其他檔案,首次通路會不會變慢。于是重新開機IIS,然後發現首次通路該目錄中的第一個檔案(不論首次通路的是哪個檔案),都會耗時數秒;如果Attach到w3wp,都會Catch到這個異常。

5. 項目是從.net framework 1.1(VS2003)上直接更新過來的,以前03的版本,木有這個問題。然後google“asp.net 4.0 slow”,找到下面這個:

6. The very first time that the page is load, then the asp.net compile a lot of pages, almost every one found on the same dir, including modules, and dlls found on bin.也就是說,在首次請求一個目錄下的某個檔案時,會把該目錄的所有檔案都編譯一下。這樣做的好處是,把一個目錄的編譯操作都集中在首次通路上,後續請求會比較快;但這樣帶來的問題是,如果編譯時間比較久,那第一個發起請求的人就杯具了。于是在配置檔案中,<code>設定batch="false"</code>,然後問題消失,首次請求的速度提上來了,attach上去也沒有異常了。

   部署的時候,記得在配置檔案中,把debug和batch關閉,把optimizeCompilations打開:

    &lt;compilation targetFramework="4.0" debug="false" batch="false" optimizeCompilations="true"&gt;

繼續閱讀