AppDomain.Unload不会卸载程序集

时间:2016-11-16 14:50:44

标签: c# .net reflection .net-assembly

我尝试检查程序集的某些元数据而不将其(永久地)加载到我的应用程序中。为此,我创建了一个临时的sandbox AppDomain,将程序集加载到其中,然后卸载整个sandbox。根据{{​​3}}的答案,""正确"这样做的方法。

然而,在卸载程序集后,它仍然保留在当前的AppDomain中。为什么呢?

this question的答案表明集会可能会被放入"当前的域名,但我不知道在我的例子中这怎么可能。应用程序的其余部分根本不使用程序集,甚至没有引用它。即使在组装加载后立即卸载sandobx,观察到的行为仍然存在。

this question表示无法以这种方式卸载与域无关的程序集。这是什么原因?如果是的话,我能以某种方式阻止程序集被视为域中立吗?

private void Check()
{
    string assemblyName = "SomeUnrelatedAssembly";
    var sandbox = AppDomain.CreateDomain("sandbox"); //create a discardable AppDomain
    //load the assembly to the sandbox
    byte[] arr;
    using (var memoryStream = new MemoryStream())
    {
        using (var fileStream = new FileStream($"{assemblyName}.dll", FileMode.Open))
            fileStream.CopyTo(memoryStream);
        arr = memoryStream.ToArray();
    }

    Console.WriteLine(IsAssemblyLoaded(assemblyName)); //prints false
    sandbox.Load(arr);

    //and unload it     
    AppDomain.Unload(sandbox);      
    Console.WriteLine(IsAssemblyLoaded(assemblyName)); //prints true!
}

private static bool IsAssemblyLoaded(string assemblyName)
{
    return AppDomain.CurrentDomain.GetAssemblies().Any(a => a.FullName.Contains(assemblyName));
}

编辑:我已使用Process Explorer(例如This article)检查了加载过程。加载的程序集不是域中立的。

1 个答案:

答案 0 :(得分:1)

你是对的。您的程序集被视为域中立,并在应用程序域之间共享。

使用允许您提供设置信息的AppDomain.CreateDomain重载:

的信息:

[(ngModel)]="selectedLanguage"

变化:

li

要:

AppDomainSetup info = new AppDomainSetup();
info.ApplicationBase = domainDir;
info.ApplicationName = executableNameNoExe;
info.LoaderOptimization = LoaderOptimization.SingleDomain;