微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

卸载 appdomain 后程序集仍然存在

如何解决卸载 appdomain 后程序集仍然存在

我有程序,它创建 AppDomain,在其中加载程序集 prelude,然后卸载 AppDomain。最后,程序列出了来自认 appdomain 的程序集。它是程序的简化版本。在下一个版本中,prelude.dll 将在运行时更改并通过 appdomain 持续执行/卸载。

namespace appdomaintest
{

    class Program
    {
        static void log_assemblies(AppDomain domain)
        {
            foreach (var item in domain.GetAssemblies())
            {
                Console.WriteLine($"{domain.FriendlyName} : {item.FullName}");
            }
        }
        static void Main(string[] args)
        {
            {
                var prelude_domain = AppDomain.CreateDomain("PreludeDomain#1",null,null);
                var asm = prelude_domain.Load(new System.Reflection.AssemblyName("prelude"));
                var myint = prelude_domain.CreateInstanceAndUnwrap("prelude","prelude.MyInt");
                myint.GetType().getmethod("show").Invoke(myint,new object[0]);
                AppDomain.Unload(prelude_domain);
                Console.WriteLine("AppDomain was unloaded");
            }
            log_assemblies(AppDomain.CurrentDomain);
        }
    }
}  

这是prelude.dll内容

public class MyInt : MarshalByRefObject
{
    public MyInt()
    {
        Console.WriteLine($"MyInt was constructed in {AppDomain.CurrentDomain.FriendlyName}");
    }
    public void show()
    {
        Console.WriteLine($"show in {AppDomain.CurrentDomain.FriendlyName}");
    }
}

这是程序的输出

MyInt was constructed in PreludeDomain#1
show in PreludeDomain#1
AppDomain was unloaded
appdomaintest.exe : mscorlib,Version=4.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089
appdomaintest.exe : appdomaintest,Version=1.0.0.0,PublicKeyToken=null
appdomaintest.exe : prelude,PublicKeyToken=null

不幸的是,我发现我的认应用程序域包含 prelude.dll 程序集。据我了解,它会一直持续到我的程序执行结束。有什么方法可以防止将其加载到认应用程序域?在未来的版本中,prelude.dll 将被重复加载/卸载(它的元数据也将被修改)。这就是为什么这种行为不适合我的目的。

在我看来,创建代理对象可能会导致将元数据加载到认域。但是我怎样才能卸载它们呢?

解决方法

它会保留,是的。没有办法解决它,因为微软在此处声明这是不可能的:https://docs.microsoft.com/en-us/dotnet/framework/app-domains/how-to-unload-an-application-domain

使用与另一个进程的进程间通信。您可以启动进程并在其中加载任何内容,直到它变得臃肿,然后您只需杀死它并重新开始。

您从中获得的一个好处 - 没有人会导致您的应用程序因意外调用此库中不安全的内容而崩溃。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。