我想知道如何卸载加载到主AppDomain中的程序集.
我有以下代码:
var assembly = Assembly.LoadFrom( FilePathHere );
当我完成时,我需要/希望能够卸载这个程序集.
谢谢你的帮助.
您无法从appdomain卸载程序集.您可以销毁appdomains,但是一旦将程序集加载到appdomain中,它就会存在于appdomain的生命周期中.
请参阅Jason Zander关于为何没有Assembly.Unload方法的解释?
如果您使用的是3.5,则可以使用AddIn Framework来更轻松地管理/调用不同的AppDomain(您可以卸载,卸载所有程序集).如果您之前使用的是版本,则需要自己创建一个新的appdomain来卸载它.
我也知道这已经很老了,但可能会帮助有这个问题的人!这是我发现的一种方法!而不是使用:
var assembly = Assembly.LoadFrom( FilePathHere );
用这个:
var assembly = Assembly.Load( File.ReadAllBytes(FilePathHere));
这实际上加载了程序集文件的"内容",而不是文件本身.这意味着程序集文件上没有文件锁!所以现在它可以复制,删除或升级而无需关闭您的应用程序或尝试使用单独的AppDomain或Marshaling!
PROS:使用1个代码修复非常简单! 缺点:不能使用AppDomain,Assembly.Location或Assembly.CodeBase.
现在您只需要销毁在程序集上创建的任何实例.例如:
assembly = null;
如果不卸载整个AppDomain,则无法卸载程序集.原因如下:
您正在应用程序域中运行该代码.这意味着可能存在呼叫站点和调用堆栈,其中包含期望继续工作的地址.
假设您确实设法跟踪程序集的所有句柄和对已运行代码的引用.假设您没有使用代码,一旦成功释放了程序集,您就只释放了元数据和IL.JIT代码仍然在app域加载器堆中分配(JIT'd方法按照调用它们的顺序在缓冲区中按顺序分配).
最后一个问题涉及已加载共享的代码,否则更正式地称为"域中立"(在ngen工具上签出/共享).在此模式下,生成程序集的代码将从任何应用程序域执行(没有硬连线).
建议您自然地围绕应用程序域边界设计应用程序,完全支持卸载.
您应该将临时程序集加载到另一个程序集中AppDomain
,当不使用时,您可以卸载它AppDomain
.这是安全和快速的.