C# Assembly已停用无法执行代码:问题原因及解决方法
问题
尝试通过反射访问自行创建的DLL时,出现**“Assembly已停用,无法执行任何代码”**的错误——只有在访问指定路径的ReferencedAssemblies中代码前能正常运行。已通过以下代码生成DLL,且文件已在正确目录生成,求错误成因及解决办法。
生成DLL的代码:
public class DLLCreator { private string path = @"G:\Scripts\Bremca\Library\"; [Start] public void Start() { List<string> paths = new List<string>(); //Class File Location DirectoryInfo d = new DirectoryInfo(path); FileInfo[] files = d.GetFiles("*.cs"); foreach(FileInfo file in files) { if(!file.Name.Contains(this.ToString())) paths.Add(file.FullName); } string[] pathsArray = paths.ToArray(); CSharpCodeProvider provider = new CSharpCodeProvider(); CompilerParameters parameters = new CompilerParameters(); parameters.ReferencedAssemblies.Add("System.dll"); parameters.ReferencedAssemblies.Add("System.Drawing.dll"); parameters.ReferencedAssemblies.Add("System.Windows.Forms.dll"); parameters.ReferencedAssemblies.Add("System.Runtime.dll"); parameters.ReferencedAssemblies.Add(@"G:\Scripts\Bremca\Bin\Eplan.EplApi.AFu.dll"); parameters.ReferencedAssemblies.Add(@"G:\Scripts\Bremca\Bin\Eplan.EplApi.Baseu.dll"); parameters.ReferencedAssemblies.Add(@"G:\Scripts\Bremca\Bin\Eplan.EplApi.HEServicesu.dll"); parameters.ReferencedAssemblies.Add(@"G:\Scripts\Bremca\Bin\Eplan.EplApi.DataModelu.dll"); parameters.ReferencedAssemblies.Add(@"G:\Scripts\Bremca\Bin\Eplan.EplApi.MasterDatau.dll"); parameters.ReferencedAssemblies.Add("System.Collections.dll"); parameters.ReferencedAssemblies.Add("System.Runtime.InteropServices.dll"); parameters.ReferencedAssemblies.Add("System.Xml.dll"); parameters.ReferencedAssemblies.Add("System.Xml.ReaderWriter.dll"); parameters.ReferencedAssemblies.Add("System.Linq.dll"); parameters.ReferencedAssemblies.Add("System.Core.dll"); parameters.ReferencedAssemblies.Add("System.ComponentModel.Primitives.dll"); parameters.ReferencedAssemblies.Add("System.Drawing.Primitives.dll"); parameters.OutputAssembly = path+"Library.dll"; parameters.GenerateInMemory = true; //True - memory generation, false - external file generation parameters.GenerateExecutable = false; //True - exe file generation, false - dll file generation //Compile Assembly CompilerResults results = provider.CompileAssemblyFromFile(parameters, pathsArray); if (results.Errors.HasErrors) { StringBuilder sb = new StringBuilder(); foreach (CompilerError error in results.Errors) { sb.AppendLine(String.Format("Error ({0}): {1}", error.ErrorNumber, error.ErrorText)); } throw new InvalidOperationException(sb.ToString()); } provider.Dispose(); } }
错误截图:
错误成因与解决方案
成因分析
内存程序集被GC提前回收
你开启了GenerateInMemory = true,编译后的程序集会加载到内存,但CompilerResults和CSharpCodeProvider在Start方法执行完后会被垃圾回收器回收,连带内存中的程序集被标记为不可用,后续反射访问时就会触发“Assembly已停用”的错误。磁盘DLL未被实际加载
虽然指定了OutputAssembly路径,但因为优先内存生成,磁盘上的DLL只是编译副本,如果你后续反射时试图访问内存中已被回收的程序集,自然会报错。
解决办法
方案一:关闭内存生成,直接用磁盘DLL
把GenerateInMemory改为false,让编译器直接生成磁盘DLL,后续反射从磁盘路径加载:
parameters.GenerateInMemory = false; // 修改为false,生成磁盘文件
之后用Assembly.LoadFrom(path + "Library.dll")加载程序集,彻底避开内存回收问题。
方案二:保留内存生成,持有程序集引用
如果必须在内存中生成,要在类级别保存程序集引用,防止被GC回收:
- 在
DLLCreator类里加一个字段:private Assembly compiledAssembly; - 编译完成后存下引用:
compiledAssembly = results.CompiledAssembly;
后续反射操作直接用这个compiledAssembly对象,别再通过路径重新加载。
方案三:检查第三方DLL的可用性
确认你添加的Eplan系列DLL路径正确、版本和运行环境兼容,且当前程序有权限访问这些文件——第三方DLL加载失败也可能导致生成的程序集状态异常。
内容的提问来源于Stack Exchange,提问作者Eugene Paul
相关产品推荐
相关产品推荐

