Open mike-riedel opened 6 years ago
You can get more details on what is happening by hooking into the following events:
StackExchange.Precompilation.RoslynRazorViewEngine.CompilingPath += OnRuntimeCompilation;
System.Web.WebPages.Razor.RazorBuildProvider.CompilingPath += OnRuntimeCompilation;
... and have the handler log it somewhere:
private static void OnRuntimeCompilation(object sender, System.Web.WebPages.Razor.CompilingPathEventArgs e)
{
// TODO log details somewhere
}
There are also other thing asp.net tries to build at runtime, like global.asax, helpers, etc.
There is a workaround for global.asax in the test project via the PreApplicationStartMethodAttribute and the correct handler.
If you're sure you're not using anything else, you can also add a PrecompiledApp.config to you web application project with the following content:
<?xml version="1.0"?>
<precompiledApp version="42" updatable="true"/>
It tells the BuildManager not to attempt building any special-purpose folders such as App_Code, App_GlobalResources, and App_WebReferences, and special files such as Global.asax.
Thanks for the helpful information and suggestions.
I added trace output for those events, applied the global.asax workaround and create the PrecompiledApp.config file. The traces show a runtime compilation event whenever a "new" .cshtml page is requested. In other words, if the same page is requested multiple times, the event only occurs for the first request. The sender of the events is always System.Web.WebPages.Razor.RazorBuildProvider.
You can get a list of all precompiled views the precompiled view engine knows about via the PrecompiledViewEngine.ViewPaths
property. If they aren't there, you didn't initialize it correctly. If they are, plase elaborate, as something might be broken in the path resolution / normalization.
I have two web projects in the same solution, one for sign-in and the other for whatever. The sign-in app never fires a runtime compilation event when its pages are requested. But the admin app wants to runtime-compile every page other than "~/index.cshtml". While debugging, PrecompiledViewEngine.ViewPaths
contains reasonable paths which look like they should correlate with a particular Request.Url
and in one case it seems to work and in the other it does not.
For example, ViewPaths
contains "~/app/services/services.cshtml"
and a request comes in with RawUrl = "/rightfaxsdk/admin/app/services/services.cshtml"
and AppRelativeCurrentExecutionFilePath = "~/app/services/services.cshtml"
, which is an exact match for the entry in ViewPaths. But the CompilingPath event is fired, which to me means the page is being compiled.
I've spent hours looking for relevant differences between the two apps, including detailed file diffs, but haven't found anything that seems important. The sign-in app has a lot less pages (10 instead of 89) but I can't imagine that would matter.
We use HttpContext.RewritePath for most incoming requests (primarily to remove cache-busting fingerprints). Could the resulting changes to the Request cause the caching not to locate the correct precompiled file?
Maybe, if you use partial view names (e.g. View("Foo")
, or just View()
inside the Foo
method). Have you tried specifying the full view path instead (e.g. View("~/Views/Bar/Foo.cshtml")
)?
Adding to this, I found that using the package with VS2015, I consistently get this error message:
3>CSC : warning : Couldn't load reference 'System.Runtime, Version=4.0.20.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' from 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\Facades\System.Runtime.dll' - 'Could not load file or assembly 'System.Runtime, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. An operation is not legal in the current state. (Exception from HRESULT: 0x80131509)'
3>CSC : error : An unhandled exception occured
3>CSC : error : System.IO.FileNotFoundException: Could not load file or assembly 'System.Runtime, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
Using VS2017, we do not see these build errors. Following the guide to copy the DLLs into the tools directory results in a different error when using VS2015:
3>CSC : warning : Couldn't load reference 'System.Runtime, Version=4.0.20.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' from 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\Facades\System.Runtime.dll' - 'Could not load file or assembly 'System.Runtime, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. An operation is not legal in the current state. (Exception from HRESULT: 0x80131509)'
3>C:\Program Files (x86)\MSBuild\14.0\bin\Microsoft.CSharp.Core.targets(67,5): error MSB6006: "StackExchange.Precompiler.exe" exited with code -1073741819.
For now I have migrated to VS2017, Is this likely to be due to the MSBuild version used? Or related to dependency resolution?
I believe I've followed the necessary steps to use precompiled .cshtml views but when I run my web app and click on various pages, I still see significant delays and see VBCSCompiler.exe appearing in Task Manager, leading me to believe that the precompiled views are not being used.
Do I have the wrong expectations about what this package does or am I doing something wrong?
I followed these steps, per the instructions on github:
In the build output I've verified StackExchange.Precompiler.exe is being run, and while debugging I've verified PrecompiledViewEngine is finding what seem to be precompiled views in the project's assembly. And yet, I still see long delays and VBCSCompiler being run whenever new cshtml views are accessed.