我有一个Windows Azure Web角色,其中包含一个使用 ASP.NET MVC的网站。当HTTP请求到达并且首次加载页面时,视图(.aspx或.cshtml(将被编译,这需要一些时间,因此第一次提供页面时,它比稍后提供同一页面需要更长的时间。
我已经启用了<MvcBuildViews>
(在此答案中描述(来强制对视图进行编译时验证,但这似乎对部署和运行时的编译没有任何影响。
Azure Web 角色具有所谓的启动任务,还有一个特殊的OnStart()
方法,我可以在其中放置任何预热代码,因此一旦我知道该怎么做,将其添加到角色中就不是问题。
有没有办法强制编译所有视图?
看看 David Ebbo 的预编译 Razor 视图
你为什么要这样做?
这样做的一个原因是避免在您的网站出现任何运行时命中 启动,因为在运行时没有要编译的内容。这可以是 在具有许多视图的网站中很重要。
此外,您不再需要部署 cshtml 文件,从而导致 在较小的部署文件集中。
另一个很酷的好处是它使您能够进行单元测试 你的观点,这一直是非常困难的 标准运行时编译模型。我将在 未来的帖子。
事实证明,可以使用 ClientBuildManager.PrecompileApplication 执行 ASP.NET 预编译并模仿按需编译行为,但只是编译每个页面。试过了 - 第一次加载看起来明显更快。
重要的部分是作为构造函数参数传递的内容ClientBuildManager
。解决方案是枚举 Site
对象的所有.Applications
,并为 .Applications
中的每个项枚举所有.VirtualDirectories
,并使用每个项的Path
和VirtualPath
作为构造函数ClientBuildManager
参数。
这是初始负载问题还是稳定状态问题?看到的一个问题是应用程序池回收,默认为 20 分钟超时。如果禁用超时(或将其设置为较大的超时(,这是有效的解决方法吗?
这是另一个讨论应用程序池超时以及如何禁用它的 SO 答案。基本上:
%windir%system32inetsrvappcmd set config -section:applicationPools -applicationPoolDefaults.processModel.idleTimeout:00:00:00
将此添加到 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();
}
如果使用Visual Studio的发布功能,则有一个更简单的选项:
在">发布"对话框>"设置"窗格中,展开"文件发布选项"并选中">发布期间预编译",然后单击"配置"。在"高级预编译设置"对话框中,取消选中"允许预编译站点可更新"。
来源: https://msdn.microsoft.com/en-us/library/hh475319.aspx