Azure预编译似乎不起作用

时间:2014-01-21 21:27:07

标签: asp.net asp.net-mvc azure azure-web-roles

我尝试预编译我的Azure WebApplication,因此第一次点击对于页面的每次首次点击都不会花费多秒。

我的WebRole.Run()中有以下代码:

using ( var server_manager = new ServerManager() )
{
    var main_site               = server_manager.Sites[RoleEnvironment.CurrentRoleInstance.Id + "_Web"];
    var main_application        = main_site.Applications["/"];
    var main_application_pool   = server_manager.ApplicationPools[main_application.ApplicationPoolName];

    string physical_path = main_application.VirtualDirectories["/"].PhysicalPath;

    main_application["preloadEnabled"] = true;
    main_application_pool["autoStart"] = true;
    main_application_pool["startMode"] = "AlwaysRunning";

    server_manager.CommitChanges();

    Log.Info( "Building Razor Pages", "WebRole" );

    var build_manager = new ClientBuildManager( "/", physical_path );
    build_manager.PrecompileApplication();

    Log.Info( "Building Razor Pages: Done", "WebRole" );
}

它似乎没有抛出任何异常,当我查看日志时,build_manager.PrecompileApplication()需要大约55秒。

似乎对我来说是正确的。

除非我第一次尝试加载页面时仍然会受到影响。如果我查看MiniProfiler,我特别看到查找部分需要很长时间。我仍然怀疑它是编译,因为1.5秒只是找到一个文件对我来说似乎有点长。

enter image description here

我的方法上面有什么问题吗?有没有办法检查页面是否真的编译?在 编译的情况下,还有什么呢?为什么o为什么这么复杂......

2 个答案:

答案 0 :(得分:2)

我从来没有太开始工作。可能是一些奇怪的Web.config / Azure /项目设置似乎已关闭,但我从未找到它。

在您进一步阅读之前,我建议您首先为您的项目尝试此方法:https://stackoverflow.com/a/15902360/647845。 (因为它不依赖于黑客攻击)

我的解决方法相对简单,我在应用程序中搜索所有Razor Views,而不是仅仅尝试使用模拟ControllerContext渲染它们,而忽略了结果。由于ViewModel无效,所有View都会抛出异常,但只要视图首先被编译就无所谓。

private void PrecompileViews()
{
    string search_path = GetSearchPath();

    // Create a dummy ControllerContext - using the HomeController, but could be any controller
    var http_context = new HttpContext( new HttpRequest("", "http://dummy", ""), new HttpResponse(new StringWriter()) );
    http_context.Request.RequestContext.RouteData.Values.Add( "controller", "Home" );
    var controller_context = new ControllerContext( new HttpContextWrapper(http_context), http_context.Request.RequestContext.RouteData, new HomeController() );

    // loop through all views, and try to render them with the dummy ControllerContext
    foreach ( var file in Directory.GetFiles(search_path, "*.cshtml", SearchOption.AllDirectories) )
    {
        string relative_view_path = "~" + file.Replace( search_path, "", StringComparison.InvariantCultureIgnoreCase );

        var view_result = new ViewResult { ViewName = relative_view_path };

        try
        {
            view_result.ExecuteResult( controller_context );
        }
        catch (Exception)
        {
            // Almost all views will throw exceptions, because of a non valid ViewModel, 
            // but that doesn't matter because the view stills got compiled
        }
    }
}

GetSearchPath返回应用程序的根目录:

private string GetSearchPath()
{
    string bin_path = Path.GetDirectoryName( Assembly.GetExecutingAssembly().GetName().CodeBase );
    string local_path = new Uri(bin_path).LocalPath;
    return Path.GetFullPath( Path.Combine( local_path, ".." ) );
}

我在Global.asax的末尾称之为全部:

protected void Application_Start()
{
     [...]
     PrecompileViews();
 }

答案 1 :(得分:1)

剃刀生成器可以在保存或构建时编译您的视图。这样,您可以将程序集中的已编译视图上传到azure。

http://razorgenerator.codeplex.com/