【问题标题】:How do I force compilation of ASP.NET MVC views?如何强制编译 ASP.NET MVC 视图?
【发布时间】:2012-05-16 12:32:42
【问题描述】:

我有一个 Windows Azure Web 角色,其中包含一个使用 ASP.NET MVC 的网站。当 HTTP 请求到达并首次加载页面时,会编译视图(.aspx 或 .cshtml),这需要一些时间,因此第一次提供页面所需的时间明显长于稍后提供同一页面的时间。

我已启用 <MvcBuildViews>(描述为 in this answer)以强制执行视图的编译时验证,但这似乎对站点部署和运行时的编译没有任何影响。

Azure Web 角色有所谓的启动任务,还有一个特殊的 OnStart() 方法,我可以在其中放置任何预热代码,所以一旦我知道要做什么,将其添加到角色中就不是问题了。

有没有办法强制编译所有视图?

【问题讨论】:

    标签: asp.net .net asp.net-mvc iis azure


    【解决方案1】:

    看看Precompiled Razor Views by David Ebbo

    您为什么要这样做?

    这样做的一个原因是避免您的网站在运行时受到任何影响 开始,因为在运行时没有任何东西可以编译。这可以是 在有很多浏览量的网站中很重要。

    此外,您不再需要部署 cshtml 文件,从而 在较小的部署文件集中。

    另一个很酷的好处是它使您能够进行单元测试 你的意见,这一直是一件非常困难的事情 标准运行时编译模型。我将在 未来的帖子。

    【讨论】:

    • 我不确定,因为我只将它用于 Razor 视图
    【解决方案2】:

    原来有ASP.NET Precompilation 可以使用ClientBuildManager.PrecompileApplication 执行并模仿按需编译行为,但只是编译每个页面。试过了 - 第一次加载看起来明显更快。

    重要的部分是作为ClientBuildManager 构造函数参数传递的内容。解决方案是枚举Site对象的所有.Applications,并为.Applications中的每个项目枚举所有.VirtualDirectories,并使用每个项目中的PathVirtualPath作为ClientBuildManager构造函数的参数。

    【讨论】:

    • 在创建ClientBuildManager 类时提供哪些字符串作为参数?
    • @trailmax:我得到了应用程序的VirtualDirectory 对象,并从中得到Path 作为第一个参数,PhysicalPath 作为第二个参数。
    【解决方案3】:

    这是初始负载问题还是稳态问题?看到的一个问题是应用程序池回收问题,默认为 20 分钟超时。如果您禁用超时(或将其设置为较大的值),这是一个有效的解决方法吗?

    这里是another SO answer 讨论 AppPool 超时以及如何禁用它。基本上:

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

    【讨论】:

    • 这是另一个我不知道的问题。非常感谢。但是,我询问是否将 ASP.NET 视图编译为可执行代码,并且无论 apppool 是否被回收,这仍然必须完成。您知道为什么首先要进行回收吗?我的意思是我部署了一个网络角色以始终拥有一个网站。为什么要回收?
    • AppPool 回收与 Windows Server AppPool 回收相同。我已经看到了为 Windows Azure 更改此设置的论点,但是 Windows Server on-prem 和 Windows Azure 之间存在不一致,目标是保持一致。在高流量情况下,您可能不会遇到回收问题。使用上面的代码很容易调整,并且无论是在本地还是在云端都可以正常工作。
    【解决方案4】:

    将此添加到 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();
            }
    

    【讨论】:

      【解决方案5】:

      如果您使用 Visual Studio 的发布功能,还有一个更简单的选项:

      Publish 对话框 > Settings 窗格中,展开 File Publish Options 并选中 Precompile during publishing 然后点击配置。在高级预编译设置对话框中,取消选中 允许预编译的站点可更新

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

      【讨论】:

        猜你喜欢
        • 2011-04-02
        • 2011-08-13
        • 2010-09-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多