在C++中加载和卸载DLL是一件很容易的事,LoadLibrary和FreeLibrary让你能够轻易的在程序中加载DLL,然后在任何地方卸载。在C#中我们也能使Assembly.LoadFile实现动态加载DLL,但是当你试图卸载时,你会很惊讶的发现Assembly没有提供任何卸载的方法。这是由于托管代码的自动垃圾回收机制会做这件事情,所以C#不提供释放资源的函数,一切由垃圾回收来做。

这引发了一个问题,Assembly加载的DLL可能只在程序结束的时候才会被释放,这也意味着在程序运行期间无法更新被加载的DLL。而这个功能在某些程序设计时是非常必要的,考虑你正在反射机制写一个查看DLL中所有函数详细信息的程序,程序提供一个菜单让户可以选择DLL文件,这时就需要让程序能够卸载DLL,否则一旦户重新得到新版本DLL时,必须要重新启动程序,重新选择加载DLL文件,这样的设计是户无法忍受的。

C#也提供了实现动态卸载DLL的方法,通过AppDomain来实现。AppDomain是一个独立执行应程序的环境,当AppDomain被卸载的时候,在该环境中的所有资源也将被回收。关于AppDomain的详细资料参考MSDN。下面是使AppDomain实现动态卸载DLL的代码,

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()来得到

转载:地址不详^_^

最新文章

  1. Oracle数据库根据时间查询
  2. PHP 类型判断和NULL,空值检查
  3. Jquery实现下拉联动表单
  4. [stm32][ucos] 1、基于ucos操作系统的LED闪烁、串口通信简单例程
  5. Java、Hibernate(JPA)注解大全
  6. 根据包名字符串跳转Activity
  7. Ajax、反向Ajax和WebSocket 概念
  8. 动态调用WCF服务
  9. ARM(ARM处理器)
  10. 【转载】ACM总结——dp专辑
  11. [置顶] Flex中Tree组件无刷新删除节点
  12. c语言字符串库函数#include<string.h>
  13. 【转】BeagleBone Black USB一线通(3)
  14. sqlserver练习
  15. Java程序设计环境概述
  16. Redis 内存管理与事件处理
  17. Pycharm+django新建Python Web项目
  18. 三十天学不会TCP,UDP/IP网络编程 - 绅士的开始
  19. 2014年第五届蓝桥杯JavaB组省赛试题解析
  20. Matlab ------ 打开MATLAB,设置默认打开的文件夹

热门文章

  1. Xcode5 编译ffmpeg,arm64版本;H264
  2. datatables 服务器返回数据后的处理-表格数据属性的操作方法(ajax.dataSrc)
  3. apache开源项目 -- Tuscany
  4. DrawDib函数组的使用
  5. Squid 反向代理加速网站
  6. jvm内部现成运行
  7. 【转】http-equiv的含义
  8. hdu 1505(dp求最大子矩阵)
  9. [Everyday Mathematics]20150128
  10. JVM 性能调优实战之:使用阿里开源工具 TProfiler 在海量业务代码中精确定位性能代码