0

To evaluate as a metric for performance, I would like to keep statistics on how frequently an asp.net website project is compiled to MSIL code. As described in this post When does an ASP.NET Website project recompile?, there are several things that can trigger a re-compile to occur.

I am not interested in application pool restarts except when they cause a re-compile to happen.

One possibility is monitoring the temporary folder for compiles. If I delete the contents of %FrameworkInstallLocation%\Temporary ASP.NET Files, I can see that new timestamped files are created from run-time compile when I access the website. However, I do not understand the layout of the subdirectories.

What are some possibilities to track, log, or otherwise detect when an ASP.NET website project has performed an automatic, dynamic recompile?

Community
  • 1
  • 1
pierce.jason
  • 750
  • 6
  • 11
  • Could you describe what do you want to do ? Who have to detect it ? the website itself ? or an external application ? – Cyril Durand Mar 31 '15 at 07:45
  • Either way would be fine. If there's a method or process that could be used within the website, I could write to a log file. Or if an external application could detect or log the recompile that would be acceptable as well. – pierce.jason Mar 31 '15 at 14:32
  • One more question. You want to know when the application restart or only when the application has been recompiled ? What do you mean by recompile ? One possible way to do something is to listen on the `AppDomain.ProcessExit` event and then look at `HostingEnvironment.ShutdownReason` – Cyril Durand Mar 31 '15 at 16:28

1 Answers1

0

You can create a custom IAssemblyPostProcessor and register it using the assemblyPostProcessorType attribute of the compilation section of your web.config.

Example :

public class LoggingPostProcessor : IAssemblyPostProcessor
{
    public void PostProcessAssembly(String path)
    {
        Trace.Write(String.Format("Processing assembly : {0}", path));
    }

    public void Dispose()
    { }
}

And register it in your web.config like this :

<system.web>
    <!-- ... -->
    <compilation debug="true" targetFramework="4.5" 
                 assemblyPostProcessorType="ns.LoggingPostProcessor, assemblyName" />
</system.web>

But ASP.net won't compile the application into a single assembly, the IAssemblyPostProcessor will be called each time an assembly is compiled by ASP.net.

If you want to intercept only compilation of some resource you can create a custom BuildProvider but it may requires more work.

Cyril Durand
  • 15,834
  • 5
  • 54
  • 62
  • Since this requires putting in assemblyName, is it correct that this will only work in Web Application and not Website Projects? I cannot find any information on how to fill in assemblyName for Website Projects since each individual page within the project will get a new assembly name each time a page compiles. – pierce.jason Apr 02 '15 at 20:40
  • Also, can we get the source file name in PostProcessAssembly or only the output file name? This would better help identify what is being compiled. – pierce.jason Apr 02 '15 at 20:47
  • You can use a Class Library project to host your PostProcessor and then reference this project on your website or register this assembly into the GAC. In this case, the website don't have to reference your project. – Cyril Durand Apr 02 '15 at 22:02
  • ASP.net compilation is quite complex, more than 1 file will be compiled into one assembly. Using this solution, it is not possible to have the source file of the assembly. If you want this information, you can use Mono.Cecil to introspect the assembly or use a custom `BuildProvider`, using a BuildProvider will require more works. – Cyril Durand Apr 02 '15 at 22:06
  • This would be a good answer for an "ASP.NET Web Application". However, it does not work for an "ASP.NET Web Site" because there is no way to know assemblyName to put in assemblyPostProcessorType="ns.LoggingPostProcessor, assemblyName". In an "ASP.NET Web Application" project, you can select the Project in Solution Explorer and press Alt+Enter to bring up the "Property Pages" and the Assembly name will be shown under the "Application" section. Doing the same in an "ASP.NET Web Site" project, there is no "Application" section, and the other sections do not have anything about assembly. – pierce.jason Apr 13 '15 at 15:07
  • If the type is on the website, ASP.net may try to resolve the *assemblyName* by itself. Have you tried not specifying the *assemblyName* ? By the way the assembly containing the `LoggingPostProcessor` can be external to your website and lived in a standalone assembly. If you can't add references to your "ASP.net Web Site" (or copy the .dll file into the bin folder), you can register it on the GAC. – Cyril Durand Apr 13 '15 at 15:23