如何强制编译 ASP.NET MVC 视图



我有一个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,并使用每个项的PathVirtualPath作为构造函数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

最新更新