2012-05-16 320 views
15

我有一個Windows Azure Web角色,其中包含使用ASP.NET MVC的網站。當HTTP請求到達並且第一次加載頁面時,視圖(.aspx或.cshtml)被編譯並且需要一些時間,因此第一次服務頁面比晚些時候服務同一頁面要花費更長的時間。如何強制編譯ASP.NET MVC視圖?

我已啓用<MvcBuildViews>(描述爲in this answer)來強制執行視圖的編譯時驗證,但是在部署和運行該站點時,這對編譯沒有任何影響。

Azure Web角色有所謂的啓動任務,也是一種特殊的方法,我可以放置任何熱身代碼,所以一旦我知道該怎麼做,將其添加到角色中並不是問題。

是否有強制編譯所有視圖的方法?

回答

7

原來有ASP.NET Precompilation可以使用ClientBuildManager.PrecompileApplication和模仿按需編譯行爲的執行,只是編譯每個頁面。嘗試過 - 第一次加載看起來速度更快。

這個非平凡的部分是作爲ClientBuildManager構造函數參數傳遞的內容。解決方法是枚舉對象的所有.Applications,並且對於.Applications中的每個項目,列舉所有的.VirtualDirectories並使用來自每個項目的PathVirtualPath作爲參數到ClientBuildManager構造函數。

+0

創建'ClientBuildManager'類時,你提供什麼字符串作爲參數? – trailmax

+1

@trailmax:我得到應用程序的'VirtualDirectory'對象,並從中得到作爲第一個參數的'Path'和作爲第二個參數的'PhysicalPath'。 – sharptooth

14

看看Precompiled Razor Views by David Ebbo

你爲什麼要這麼做?

這樣做的一個原因是爲了避免在您的站點 啓動時發生任何運行時間衝擊,因爲在運行時沒有什麼需要編譯的。這可以是 在有很多視圖的網站中很重要。

此外,您不再需要部署cshtml文件,導致 在較小的部署文件集中。

另一個很酷的好處是它使您能夠對您的視圖進行單元測試 ,這對於 標準運行時編譯模型來說一直非常困難。我將在未來的帖子中詳細介紹 。

+0

這是否適用於.aspx? – sharptooth

+0

我不確定,因爲我只用於剃刀視圖 – archil

3

這是初始加載問題還是穩態問題?看到的一個問題是應用程序池回收,其默認時間爲20分鐘。如果您禁用超時(或將其設置爲較大),那麼這是一種有效的解決方法嗎?

這裏的another SO answer討論AppPool超時以及如何禁用它。基本上是:

%windir%\system32\inetsrv\appcmd set config -section:applicationPools -applicationPoolDefaults.processModel.idleTimeout:00:00:00 
+0

這是我不知道的另一個問題。非常感謝。不過,我正在詢問如何將ASP.NET視圖編譯爲可執行代碼,並且無論apppool是否被回收,仍然需要完成。你有什麼想法,爲什麼有一個回收的第一個地方?我的意思是我部署一個web角色,以便隨時都有一個網站。爲什麼回收? – sharptooth

+0

AppPool回收與Windows Server AppPool回收相同。我已經看到了改變Windows Azure的觀點,但是Windows Server on-prem和Windows Azure之間會出現不一致,並且目標是保持一致。在高流量的情況下,您可能不會遇到回收問題。使用上面的代碼很容易進行調整,並且工作原理相同,無論是在本地還是在雲端。 –

0

此加入的OnStart:

using (var serverManager = new ServerManager()) 
     { 
      string siteName = RoleEnvironment.CurrentRoleInstance.Id + "_" + "Web"; 
      var siteId = serverManager.Sites[siteName].Id; 
      var appVirtualDir = $"/LM/W3SVC/{siteId}/ROOT"; // Do not end this with a trailing/

      var clientBuildManager = new ClientBuildManager(appVirtualDir, null, null, 
             new ClientBuildManagerParameter 
             { 
              PrecompilationFlags = PrecompilationFlags.Default, 
             }); 

      clientBuildManager.PrecompileApplication(); 
     } 
0

如果您使用Visual Studio的發佈functionnality,有一個更簡單的選擇:

發佈對話框>設置窗格中展開文件發佈選項和檢查預發佈期間然後點擊配置。在高級預編譯設置對話框中,取消選中允許預編譯的站點可更新

來源:https://msdn.microsoft.com/en-us/library/hh475319.aspx