如何卸载从主AppDomain中的程序集?(How to unload an assembly fr

2019-06-18 01:53发布

我想知道如何卸载已加载到主AppDomain中的程序集。

我有以下代码:

var assembly = Assembly.LoadFrom( FilePathHere );

我需要/想能当我完成卸载该组件。

谢谢你的帮助。

Answer 1:

对于.NET版本的核心3.0及更高版本:

现在,您可以卸载组件。 需要注意的是应用程序域将不再在.NET提供的核心。 相反,你可以创建一个或多个AssemblyLoadContext,通过这方面加载组件,然后卸载该上下文。 见AssemblyLoadContext ,或本教程模拟加载插件,然后卸载它 。

对于.NET芯3,包括netframework 4和下前达网络版本

你不能从一个AppDomain卸载的组件。 你可以摧毁的AppDomain,但一旦一个组件加载到一个AppDomain,它的存在对应用程序域的生命。

见杰森Zander的解释为什么没有一个Assembly.Unload方法?

如果使用的是3.5,你可以使用外接程序框架,使其更易于管理/调用到不同的应用程序域(你可以卸载,卸载所有的组件)。 如果使用的是之前的版本,你需要创建一个新的AppDomain自己卸载它。



Answer 2:

我也知道这是很老了,但可能会帮助谁是有这个问题的人! 这里有一种方法我发现做到这一点! 而不是使用的:

var assembly = Assembly.LoadFrom( FilePathHere );

用这个:

var assembly = Assembly.Load( File.ReadAllBytes(FilePathHere));

这实际上加载该文件本身,而不是汇编文件的“内容”。 这意味着没有一个文件锁,放置在装配文件! 所以,现在它可以被复制,删除或升级而无需关闭应用程序或试图用一个单独的AppDomain或封送!

优点:非常简单,1个班轮的代码来解决! 缺点:不能使用的AppDomain,Assembly.Location或Assembly.CodeBase。

现在,你只需要摧毁装配创建的所有实例。 例如:

assembly = null;


Answer 3:

而不卸载整个AppDomain中无法卸载的组件。 这里的原因 :

  1. 您正在运行的应用程序域代码。 这意味着有可能调用网站和调用栈与他们期待继续工作地址。

  2. 假设你没有管理跟踪所有句柄和引用通过组装已经运行的代码。 假设您没有NGEN的代码,一旦你成功地释放了大会中,只释放了元数据和IL。 在这些JIT过代码在应用程序域加载器堆仍然被分配(这些JIT过方法在顺序的缓冲器,其中他们被称为顺序分配)。

  3. 最后一个问题涉及到已加载的共享代码,否则更正式地知道作为“域中性”(检查/在NGEN工具共享)。 在这种模式下,则生成从任意的应用程序域(没有硬连线)执行用于装配的代码。

建议您设计应用程序域边界自然,在卸载完全支持在你的应用程序。



Answer 4:

你应该载入您的临时装配在另一个AppDomain和在不使用时,那么你可以卸载AppDomain 。 它的安全和快捷。



Answer 5:

如果你想拥有它以后可以被卸载,根据您的需要临时代码DynamicMethod类可以做你想做的。 这不给你的类,虽然。



Answer 6:

这里是一个很好的例子,如何编译和运行期间运行DLL,然后卸载所有资源: http://www.west-wind.com/presentations/dynamicCode/DynamicCode.htm



Answer 7:

我知道它的旧的,但可能会帮助别人。 您可以加载从流的文件,并释放它。 它为我工作。 我找到了解决办法HERE 。

希望能帮助到你。



Answer 8:

作为替代方案,如果大会刚装摆在首位,以检查如公钥组件的信息,更好的办法是不加载它,而不是检查由加载刚刚的AssemblyName的信息在第一:

AssemblyName an = AssemblyName.GetAssemblyName ("myfile.exe");
byte[] publicKey = an.GetPublicKey();
CultureInfo culture = an.CultureInfo;
Version version = an.Version;

编辑

如果你需要,以反映集中的类型没有得到装配到您的应用程序域,您可以使用Assembly.ReflectionOnlyLoadFrom方法。 这将让你看看他们在装配类型,但不会让你实例化他们,也不会到AppDomain中加载程序集。

看下面这个例子作为exlanation

public void AssemblyLoadTest(string assemblyToLoad)
{
    var initialAppDomainAssemblyCount = AppDomain.CurrentDomain.GetAssemblies().Count(); //4

    Assembly.ReflectionOnlyLoad(assemblyToLoad);
    var reflectionOnlyAppDomainAssemblyCount = AppDomain.CurrentDomain.GetAssemblies().Count(); //4

    //Shows that assembly is NOT loaded in to AppDomain with Assembly.ReflectionOnlyLoad
    Assert.AreEqual(initialAppDomainAssemblyCount, reflectionOnlyAppDomainAssemblyCount); // 4 == 4

    Assembly.Load(assemblyToLoad);
    var loadAppDomainAssemblyCount = AppDomain.CurrentDomain.GetAssemblies().Count(); //5

    //Shows that assembly is loaded in to AppDomain with Assembly.Load
    Assert.AreNotEqual(initialAppDomainAssemblyCount, loadAppDomainAssemblyCount); // 4 != 5
}


文章来源: How to unload an assembly from the primary AppDomain?