如何从主AppDomain卸载程序集?
我想知道如何卸载加载到主AppDomain中的程序集。如何从主AppDomain卸载程序集?
我有以下代码:
var assembly = Assembly.LoadFrom(FilePathHere);
我需要/想能当我完成卸载该组件。
感谢您的帮助。
您无法从应用程序域卸载程序集。您可以销毁AppDomain,但是一旦将程序集加载到AppDomain中,它就存在于AppDomain的生命周期中。
的Why isn't there an Assembly.Unload method?
见杰森Zander的解释如果您使用的3.5,您可以使用外接程序框架,使其更易于管理/调用到不同的应用程序域(你可以卸载,卸载所有的组件) 。如果您之前使用的是版本,则需要自己创建一个新的AppDomain以卸载它。
我以为这改变了.NET 3.5? – 2008-09-23 19:52:46
有没有计划允许从应用程序域卸载程序集(我不希望他们要么,这是很难做的,那些关心将使用更安全和更清洁的解决方法)。你可以做的最好的是Khoth提到的轻量级代码生成 – ShuggyCoUk 2009-03-20 14:46:17
如果不卸载整个AppDomain,则无法卸载程序集。 Here's why:
您正在运行的应用程序域代码。这意味着有潜在的呼叫站点和呼叫堆栈,其中有地址,期望继续工作。
假设您设法跟踪程序集的所有句柄和对已运行代码的引用。假设你没有编写代码,一旦你成功地释放了程序集,你只能释放元数据和IL。 JIT'd代码仍然在应用程序域加载器堆中分配(JIT'd方法按顺序在缓冲区中按调用顺序分配)。
最后一个问题涉及已加载共享的代码,否则更正式地称为“域中立”(在ngen工具上检出/共享)。在这种模式下,程序集的代码被生成,可以从任何应用程序域执行(没有硬连线)。
建议您围绕应用程序域边界自然设计应用程序,其中完全支持卸载。
如果您想要临时代码可以随后卸载,根据您的需要,DynamicMethod
类可能会做你想做的。尽管如此,这并不能为你提供课程。
您应该在另一个AppDomain
中加载临时程序集,如果不使用,则可以卸载AppDomain
。它安全快速。
这里是一个很好的例子,如何编译和运行期间运行DLL,然后卸载所有资源: http://www.west-wind.com/presentations/dynamicCode/DynamicCode.htm
我也知道这是很旧的,但可能会帮助有这个问题的人! 这是我发现的一种方法! 而不是使用:
var assembly = Assembly.LoadFrom(FilePathHere);
使用本:
var assembly = Assembly.Load(File.ReadAllBytes(FilePathHere));
这实际上加载该文件本身,而不是汇编文件的“内容”。这意味着组件文件上没有文件锁!所以现在它可以复制,删除或升级而不关闭你的应用程序或试图使用单独的AppDomain或Marshaling!
优惠价:非常容易修复1代码! CONS:无法使用AppDomain,Assembly.Location或Assembly.CodeBase。
现在你只需要销毁在程序集上创建的所有实例。 例如:
assembly = null;
作为替代,如果组件只是装载在第一位置,以检查如公钥组件的信息,更好的方法是将不加载它,而检查信息通过首先加载AssemblyName:
AssemblyName an = AssemblyName.GetAssemblyName ("myfile.exe");
byte[] publicKey = an.GetPublicKey();
CultureInfo culture = an.CultureInfo;
Version version = an.Version;
尽量不要使用LoadFrom,它在与Load上下文不同的上下文中并可能导致问题。 – user7116 2008-09-24 01:09:32
好问题,但我看不到任何关于如何解决的清晰答案var assembly = Assembly.LoadFrom(FilePathHere); – 2012-07-13 17:09:35