当前位置: 移动技术网 > IT编程>开发语言>c# > c#动态加载卸载DLL的方法

c#动态加载卸载DLL的方法

2019年07月18日  | 移动技术网IT编程  | 我要评论
c#中通过反射可以方便的动态加载dll程序集,但是如果你需要对dll进行更新,却发现.net类库没有提供卸载dll程序集的方法。在.net 中,加入了应用程序域的概念,应用

c#中通过反射可以方便的动态加载dll程序集,但是如果你需要对dll进行更新,却发现.net类库没有提供卸载dll程序集的方法。在.net 中,加入了应用程序域的概念,应用程序域是可以卸载的。也就是说,如果需要对动态加载的dll程序集进行更新,可以通过以下方法解决:

新建一个应用程序域,在该应用程序域中动态加载dll,然后可以卸载掉该应用程序域。该应用程序域被卸载的时候,相关资源也会被回收。

要想这样实现,就要让你程序的currentdomain和新建的newdomain之间进行通信,穿过应用程序域的边界。从网上找到了某大牛的解决方法,抄下来留给自己看吧:

复制代码 代码如下:

using system;
using system.collections.generic;
using system.text;
using system.threading;
using system.reflection;
namespace unloaddll
{
    class program
    {
        static void main(string[] args)
        {
            string callingdomainname = appdomain.currentdomain.friendlyname;//thread.getdomain().friendlyname;
            console.writeline(callingdomainname);
            appdomain ad = appdomain.createdomain("dll unload test");
            proxyobject obj = (proxyobject)ad.createinstancefromandunwrap(@"unloaddll.exe", "unloaddll.proxyobject");
            obj.loadassembly();
            obj.invoke("testdll.class1", "test", "it's a test");
            appdomain.unload(ad);
            obj = null;
            console.readline();
        }
    }
    class proxyobject : marshalbyrefobject
    {
        assembly assembly = null;
        public void loadassembly()
        {
            assembly = assembly.loadfile(@"testdll.dll");           
        }
        public bool invoke(string fullclassname, string methodname, params object[] args)
        {
            if(assembly == null)
                return false;
            type tp = assembly.gettype(fullclassname);
            if (tp == null)
                return false;
            methodinfo method = tp.getmethod(methodname);
            if (method == null)
                return false;
            object obj = activator.createinstance(tp);
            method.invoke(obj, args);
            return true;           
        }
    }
}

注意:

1. 要想让一个对象能够穿过appdomain边界,必须要继承marshalbyrefobject类,否则无法被其他appdomain使用。

2. 每个线程都有一个默认的appdomain,可以通过thread.getdomain()来得到

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网