Skip to content

Template temporary dll deletion fails with System.UnauthorizedAccessException and files are left on disk #244

Closed
@rubu

Description

@rubu

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 in 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");

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.

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?

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions