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()来得到
您可能感兴趣的文章:
如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!
网友评论