mercredi 16 novembre 2016

AppDomain.Unload does not unload assemblies

I'm trying to check some metadata of an assembly without loading it (permanently) into my app. To do this, I create a temporary sandbox AppDomain, load the assembly into it and then unload the whole sandbox. According to the answers to this question that's "correct" way to do it.

However after unloading the assembly it still remains in the current AppDomain. Why?

The answer to this question suggest that the assembly can be "bled into" the current domain, but I don't see how can this be possible in my example. The rest of the application does not use the assembly at all, it's not even referenced. The observed behavior persists even when I unload the sandobx immediately after the assembly load.

This article says that domain-neutral assemblies cannot be unloaded this way. Is that the reason? If yes, can I somehow stop the assembly from being treated as domain-neutral?

private void Check()
{
    string assemblyName = "SomeUnrelatedAssembly";
    var sandbox = AppDomain.CreateDomain("sandbox"); //create a discardable AppDomain
    Console.WriteLine(IsAssemblyLoaded(assemblyName)); //prints false

    //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();
    }
    sandbox.Load(arr);

    //check some metadata

    //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));
}





Aucun commentaire:

Enregistrer un commentaire