我尝试预编译我的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秒只是找到一个文件对我来说似乎有点长。
我的方法上面有什么问题吗?有没有办法检查页面是否真的编译?在 编译的情况下,还有什么呢?为什么o为什么这么复杂......
答案 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。