Description
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?