AppDomain.Unload doesn't release the assembly I loaded up with Reflection [duplicate]

情到浓时终转凉″ 提交于 2019-12-03 00:33:41
Matthijs Wessels

I know this is an old question, but there still is no accepted answer. I stumbled upon this question looking for the answer, hence I think that it might be useful to post the solution I found here.

Problem

tempAppDomain.Load(assemblyFileBuffer, symbolsFileBuffer); will load the assembly into tempAppDomain, but also into the app domain executing the code. You would have to unload that app domain as well to be able to delete the file. You probably do not want to do that though.

Solution

You will have to execute the code that loads the assembly from the app domain tempAppDomain. You could use the DoCallBack function on tempAppDomain to execute code in tempAppDomain. If you load the assembly there, then you should be able to delete the file after calling tempAppDomain.Unload().

Example

class Program 
{
    private static string assemblyPath = @"C:\Users\wesselm\Documents\Visual Studio 2010\Projects\ConsoleApplication1\ConsoleApplication1\bin\Debug\ClassLibrary1.dll";

    static void Main(string[] args)
    {
        AppDomainSetup setup = new AppDomainSetup();
        setup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
        var appDomain = AppDomain.CreateDomain("myAppDomain", null, setup);

        // Loads assembly in both application domains.
        appDomain.Load(AssemblyName.GetAssemblyName(assemblyPath));

        // Only loads assembly in one application domain.
        appDomain.DoCallBack(() => AppDomain.CurrentDomain.Load(AssemblyName.GetAssemblyName(assemblyPath)));

        AppDomain.Unload(appDomain);

        File.Delete(assemblyPath);
    }
}

Sources

http://msdn.microsoft.com/en-us/library/system.appdomain.docallback.aspx
http://msdn.microsoft.com/en-us/library/36az8x58.aspx
https://stackoverflow.com/a/2475177/210336

kiii

See these pages:

http://connect.microsoft.com/VisualStudio/feedback/details/536783/vsip-assembly-file-handles-not-being-released-after-appdomain-unload

http://msdn.microsoft.com/it-it/library/43wc4hhs.aspx

Set a new AppDomain AppDomainSetup with LoaderOptimization.MultiDomainHost

E.g.

domainnew = AppDomain.CreateDomain(
    newdomain_name,
    null,
    new AppDomainSetup 
    {
        ApplicationName = newdomain_name,
        ApplicationBase = assembly_directory,
        ConfigurationFile = ConfigurationManager.OpenExeConfiguration(assemblylocation).FilePath,
        LoaderOptimization = LoaderOptimization.MultiDomainHost,
        //http://msdn.microsoft.com/it-it/library/43wc4hhs.aspx
        ShadowCopyFiles = shadowcopy ? "true" : "false",
    });

best regards

If you are reading your file like this:

FileStream assemblyFileStream = new FileStream(tempAssemblyFile, FileMode.Open);

byte[] assemblyFileBuffer = new byte[assemblyFileStream.Length];
assemblyFileStream.Read(assemblyFileBuffer, 0, (int)assemblyFileStream.Length);

your problem should be fixed if you do this:

byte[] newAssemblyBuffer = new byte[assemblyFileBuffer.Length];
assemblyFileBuffer.CopyTo(newAssemblyBuffer, 0);

and change this:

Assembly projectAssembly = tempAppDomain.Load(newAssemblyFileBuffer, symbolsFileBuffer);

Alternatively this should work as well and allow you to skip the filestream:

byte[] assemblyFileBUffer = File.ReadAllBytes(tempAssemblyFile);

You have to use a Wrapper to be able to unload successfully your AppDomain. Here you can find a good example of it - http://www.west-wind.com/presentations/dynamicCode/DynamicCode.htm

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!