AppDomain无法在x64平台目标中卸载

我有以下代码,我正在使用dynamic编译一些代码,并将其加载到一个新的应用程序域。 (实际的代码编译到内存中的DLL是在CompilerProxy声明为public class CompilerProxy : MarshalByRefObject所以我可以调用它,而它居住在不同的应用程序域)。

编译x86目标(或以32位进程运行的任何cpu)编译,运行代码,然后卸载应用程序域(作为服务帐户作为Windows服务)时,每件事情都很好用。

作为x64进程运行时(作为服务帐户作为Windows服务),代码将引发System.CannotUnloadAppDomainException 。 唯一的变化是将平台目标更改为x64(对于增加的进程内存限制,windows服务以x64运行)

下面的代码是连续运行的(没有async / await,没有等待的新任务),并且编译目标中的所有代码都被pipe理。

大量的谷歌search后,我的代码看起来是正确的,但它仍然抛出x64模式的错误(和应用程序域不卸载导致内存泄漏)

 var domain = AppDomain.CreateDomain("MyDomain"); try { //Some code that actually compiles the target code var cr = (CompilerProxy) domain.CreateInstanceFromAndUnwrap( Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"some.dll"), "CompilerProxy"); var result = cr.Compile(csharpScriptString); var collection = result as CompilerErrorCollection; if (collection != null) { //Log errors when compiling the target code return; } try { //Uses reflection to find the interface impl and run. cr.Run(typeof (SomeInterface), "SomeMethod", argList.ToArray()); } //Some Error handling for the running code catch (Exception ex) { //error handling } } catch (Exception ex) { //more error handling } finally { //Every thing works in both x86 and x64 until here AppDomain.Unload(domain); } 

编辑:这是编译器代理

 public class CompilerProxy : MarshalByRefObject { private Assembly _assembly = null; public object Compile(string code, params string[] requiredAssemblies) { var codeProvider = new CSharpCodeProvider(); var parameters = new CompilerParameters { GenerateExecutable = false, // Create a dll GenerateInMemory = true, // Create it in memory WarningLevel = 3, // Default warning level CompilerOptions = "/optimize", // Optimize code TreatWarningsAsErrors = false // Better be false to avoid break in warnings }; var assemblies = AppDomain.CurrentDomain .GetAssemblies() .Where(a => !a.IsDynamic) .Select(a => a.Location); parameters.ReferencedAssemblies.AddRange(assemblies.ToArray()); var results = codeProvider.CompileAssemblyFromSource(parameters, code); if (results.Errors.Count != 0) { return results.Errors; } this._assembly = !results.Errors.HasErrors ? results.CompiledAssembly : null; return this._assembly != null; } public object Run(Type typeToInstaniate, string methodName, object[] args) { var type = _assembly.GetTypes().FirstOrDefault(typeToInstaniate.IsAssignableFrom); if (type == null) { throw new ArgumentException(); } var methodInfo = type.GetMethod(methodName); if (methodInfo == null) { throw new ArgumentException(); } object result = null; var parameters = methodInfo.GetParameters(); var classInstance = _assembly.CreateInstance(type.FullName); result = methodInfo.Invoke(classInstance, parameters.Length == 0 ? null : args); return result; } }