从App域卸载程序集

时间:2013-11-27 00:15:24

标签: c# visual-studio

代码应创建域,将dll加载到域中,卸载dll

但是在新域名上调用unload之后dll仍然存在吗?

 private void Method1()
 {
        //create new domain
        AppDomain domain = AppDomain.CreateDomain("MyDomain");
        AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;

        //load dll into new domain
        AssemblyName assemblyName = new AssemblyName();
        assemblyName.CodeBase = "c:\\mycode.dll";
        Assembly assembly = domain.Load(assemblyName);         

        //do work with dll
        //...

        //unload dll
        AppDomain.Unload(domain); 

        //still showing dll below ?????
        Assembly[] aAssemblies = AppDomain.CurrentDomain.GetAssemblies(); 
}
static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    string[] tokens = args.Name.Split(",".ToCharArray());
    System.Diagnostics.Debug.WriteLine("Resolving : " + args.Name);
    return Assembly.LoadFile(Path.Combine(new string[] { "c:\\", tokens[0] + ".dll" }));
}

为什么dll没有卸载的任何想法?

编辑(已经让它工作如下)

正如Jean指出domain.Load是问题,在同一个项目中使用CreateInstanceAndUnwrap和代理类。)

而不是

    //load dll into new domain *** this does not work
    AssemblyName assemblyName = new AssemblyName();
    assemblyName.CodeBase = "c:\\mycode.dll";
    Assembly assembly = domain.Load(assemblyName); 

到这个

    // loads proxy class into new domain               
    Type myType = typeof(Proxy);
    var value = (Proxy)domain.CreateInstanceAndUnwrap(
             myType.Assembly.FullName,
             myType.FullName);   
    //DoWork:- loads assembly into domain
    // calls methods, returns result                 
    Int32 result = value.DoWork(pathToDll);
    //Unload domain and thus assembly
    AppDomain.Unload(domain);
    //Assembly not present in current domain
    Assembly[] list = AppDomain.CurrentDomain.GetAssemblies();

将下面的类添加到当前命名空间

    public class Proxy : MarshalByRefObject
    {
        public Int32 DoWork(string assemblyPath)
        {
            try
            {
            Assembly assembly = Assembly.LoadFile(assemblyPath);
            Int32 response = 0;

            Type tObject = assembly.GetType("namespace.class");
            MethodInfo Method = tObject.GetMethod("method");

            Type myType = typeof(Proxy);
            object myInstance = Activator.CreateInstance(myType);                
            response =  (Int32) Method.Invoke(myInstance, null);

            return response;
            }
            catch (Exception ex)
            {
            throw ex;
            }
        }
    }

3 个答案:

答案 0 :(得分:1)

您无法从.NET中的Assembly卸载AppDomain,一旦程序集在域的生命周期内加载到AppDomain,就会无法卸载{。}}。

答案 1 :(得分:1)

根据经验,只要有Assembly实例,就意味着有问题的程序集会加载到当前域中。

这意味着,当您调用AppDomain.Load方法时,您将在当前域和新域中加载程序集。 (正如您在MSDN上对该方法的评论中所见,“此方法仅应用于将程序集加载到当前应用程序域中。”)

编辑:之前发布的“解决方案”已被删除,因为它实际上并未解决问题。作者在问题中编辑了一个工作解决方案。

答案 2 :(得分:1)

//still showing dll below ?????
Assembly[] aAssemblies = AppDomain.CurrentDomain.GetAssemblies();

您没有检查domain,您正在检查当前仍在加载的域名。

您无法在不拆除整个域的情况下从AppDomain卸载程序集。