2012-05-16 97 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