1
Vote

Issues with temporary dll files in 3.6.1

description

Hi,

We've been using Razor for hosting a web interface for a service successfully so far, but since upgrading from 3.3.0 to 3.6.1 we've run into an issue - we get a ton of System.UnauthorizedAccessException at the end of the program when the finalizers are called. Basically Razor complains about not being able to delete files like C:\Users\user\AppData\Local\Temp\RazorEngine_becmcjic.mja\CompiledRazorTemplates.Dynamic.RazorEngine_69ed0018c26e44dca13eba07dcb6bfd6.dll, this happens inf the CompilationData finalizer:
mscorlib.dll!System.IO.__Error.WinIOError(int errorCode, string maybeFullPath) + 0xd8 bytes
mscorlib.dll!System.IO.File.InternalDelete(string path, bool checkHost) + 0xd6 bytes    
RazorEngine.dll!RazorEngine.Compilation.CompilationData.DeleteAll() + 0x10f bytes   
RazorEngine.dll!RazorEngine.Compilation.CompilationData.Dispose(bool disposing) + 0x3b bytes    
RazorEngine.dll!RazorEngine.Compilation.CompilationData.Finalize() + 0x3d bytes 
Before the upgrade no such issues were present. The biggest change during the upgrade was that now we precompile all the templates before firing up the web interface:
       TemplateServiceConfiguration templateConfig = new TemplateServiceConfiguration();
        templateConfig.TemplateManager = new DelegateTemplateManager(name =>
        {
            string resourcePath = string.Format(viewPathTemplate, name);
            var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourcePath);
            using (StreamReader reader = new StreamReader(stream))
            {
                return reader.ReadToEnd();
            }
        });
        RazorEngineService.Create((ITemplateServiceConfiguration)templateConfig);
        RazorEngineServiceExtensions.Compile(razorEngineService, "Layout.cshtml");
        RazorEngineServiceExtensions.Compile(razorEngineService, "Cameras.cshtml", typeof(Model));
        RazorEngineServiceExtensions.Compile(razorEngineService, "Diagnostics.cshtml", typeof(Model));
        RazorEngineServiceExtensions.Compile(razorEngineService, "Index.cshtml", null);
        RazorEngineServiceExtensions.Compile(razorEngineService, "LiveView.cshtml", typeof(Model));
        RazorEngineServiceExtensions.Compile(razorEngineService, "Servers.cshtml", typeof(Model));
        RazorEngineServiceExtensions.Compile(razorEngineService, "Service.cshtml", typeof(Model));
        RazorEngineServiceExtensions.Compile(razorEngineService, "Subjects.cshtml", typeof(Model));
Since previously Razor was working quite nice already out of the box I actually haven't been digging very deep into the internals and have no idea how to approach this issue. Can anyone provide any suggestions or tell what additional information from my side would help to understand the issue? From my point of view, if the dll's are still loaded by the engine of course it won't be able to delete them, but that is just my two cents. Is there any way to make the engine unload everything?

comments

RudolfsBundulis wrote Mar 5, 2015 at 10:08 AM

I've narrowed it down to a standalone sample:
using System;
using RazorEngine;
using RazorEngine.Templating;
using RazorEngine.Configuration;
using System.Reflection;
using System.IO;

namespace RazorTest
{
    class Program
    {
        static void Main(string[] args)
        {
            TemplateServiceConfiguration templateConfig = new TemplateServiceConfiguration();
            templateConfig.TemplateManager = new DelegateTemplateManager(name =>
            {
                return "<html><head></head><body><label>Hello World!</label></body></html>";
            });
            var razorEngineService = RazorEngineService.Create((ITemplateServiceConfiguration)templateConfig);
            RazorEngineServiceExtensions.Compile(razorEngineService, "Index.cshtml");
         }
    }
}
This triggers the System.UnauthorizedAccessException on exit. Has nobody else experienced this issue?