AppDomain加载与释放dll
来源:互联网 发布:桌面工作计划安排软件 编辑:程序博客网 时间:2024/06/05 16:55
我与很多人都在找这问题的答案。还好,我很幸运,没有进入很多人都进入的死胡同而漫长的讨论中。因为我找到了这篇文章
黄天不负有心人,终于全身而退,哈哈
文章说得很明白,我去掉其他设置,只使用以下代码时
AppDomain.CurrentDomain.SetShadowCopyFiles();
在文章发布的几天后,我在微软的MSDN上发现了这文章。似乎阐述得更为系统
http://www.microsoft.com/china/msdn/library/langtool/vcsharp/csharp05162002.mspx
在加载dll时有一个奇怪现象,以下代码会报错
object objBuild = pJobDomain.CreateInstanceAndUnwrap(strDllFilePath,strClassName);
说没找到dll或依赖的项,看报错提示的路径却是实实在在有这个dll的。
于是使用以下代码
System.Reflection.Assembly asm = pJobDomain.Load(str[1]); object objBuild = asm.CreateInstance(str[0]); if(objBuild==null) Mag.Windows.Interface.Log.AddErr("buildWorker","创建对象失败"); else iDo = (Mag.Windows.Interface.IDo)objBuild;
Unload后是可以重新编译dll的。
上面的代码还有一个问题,就是我UnLoad程序域后,重新编译dll,也看到dll成功更新了。应用程序域检测到配置被修改后,重新使用上面的代码载入dll,但程序结果并不是我期待的!!程序行为还是上面版本dll的。估计是使用了缓存的dll。尝试换用以下代码
System.Runtime.Remoting.ObjectHandle objHandle = pJobDomain.CreateInstanceFrom(strDllFilePath,strClassName);object objBuild = objHandle.Unwrap();
问题解决。汗,我以为上面的代码可以用CreateInstanceAndUnwrap来代替。
设置SetShadowCopyFiles后,程序运行期间,程序文件是可以随意更新的,不过不会应用这些变化,除非重新启动程序。不过在我的项目中这个不是问题。因为主程序是极小去更新的,但相关的dll就需要不断的修正,并重新加载到程序域中。所以上文的提示已很足够了。以下是我的代码
//创建 AppDomainSetup 对象 AppDomainSetup setup = new AppDomainSetup(); setup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory; setup.ShadowCopyDirectories = "true"; //主程序很少更新,可以不设置,但考虑还要有可能, //设置后,更新完文件直接通知网管重启就可以了。不需要先关再上传文件,再通知开启这么麻烦 AppDomain.CurrentDomain.SetShadowCopyFiles(); //新域的 config 和本域公用一个。不使用默认的配置文件。 // setup.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; //安全级别相同 System.Security.Policy.Evidence adevidence = AppDomain.CurrentDomain.Evidence; //创建新的辅程序域 this.domainJob = AppDomain.CreateDomain("Mag.Web.MainSrv.Jobs",adevidence,setup); //辅程序域,dll都加载在这,更新频繁,这是一定要设置的。 this.domainJob.SetShadowCopyFiles();
加载dll
private Mag.Windows.Interface.IDo buildWorker(System.AppDomain pJobDomain,string config) { string [] str = config.Split(','); string strDllFilePath = string.Format("{0}{1}.dll",AppDomain.CurrentDomain.BaseDirectory,str[1]); string strClassName = str[0]; if(!System.IO.File.Exists(strDllFilePath)) { //throw new Exception("指定的文件不存在"); Mag.Windows.Interface.Log.AddErr("buildWorker","指定的文件不存在" + strDllFilePath); return null; } Mag.Windows.Interface.IDo iDo=null; try { //使用当前程序域加载// System.Runtime.Remoting.ObjectHandle objHandle = Activator.CreateComInstanceFrom(strDllFilePath,strClassName);// object objBuild = objHandle.Unwrap();//建立对像 System.Runtime.Remoting.ObjectHandle objHandle = pJobDomain.CreateInstanceFrom(strDllFilePath,strClassName); object objBuild = objHandle.Unwrap(); //会引起找到不dll或依赖的项的错误。// object objBuild = pJobDomain.CreateInstanceAndUnwrap(strDllFilePath,strClassName); //会首先使用缓存中的dll// System.Reflection.Assembly asm = pJobDomain.Load(str[1]);// object objBuild = asm.CreateInstance(str[0]); if(objBuild==null) Mag.Windows.Interface.Log.AddErr("buildWorker","创建对象失败"); else iDo = (Mag.Windows.Interface.IDo)objBuild; } catch(Exception ee) { // throw ee; Mag.Windows.Interface.Log.AddErr("buildWorker",ee); } return iDo; }
- AppDomain加载与释放dll
- AppDomain与Assembly的动态加载与卸载
- 内存加载SkinH.dll,不释放文件
- AppDomain 和动态加载
- Unity资源加载与释放
- AppDomain浅析与实例
- 程序集与AppDomain
- DLL调用与释放的一点切身体会
- AppDomain和动态加载 转
- 动态加载与插件系统的初步实现(二):AppDomain卸载与代理
- .NET 中动态加载DLL ,调用完之后及时释放。
- Python中CDLL加载dll后,如何释放
- C#丢弃Appdomain 之 动态dll替换
- 释放DLL 调用DLL
- AppDomain
- AppDomain
- AppDomain
- AppDomain
- InfoQ: 用Java操作Office 2007
- 可变参数的问题
- C++的动态多态和静态多态
- MSNP18协议分析(二)--- MSN登录身份认证
- windows phone:ApplicationBar图标
- AppDomain加载与释放dll
- 设置PopupWindow为圆角
- 第一次C程序设计上机报告
- iOS学习笔记15— UINavigationController的学习体会
- Problem3
- 黑马程序员-学习日记17( GUI )
- PHP对象默认按引用传递
- java读写文件大全
- linux input输入子系统分析《一》:初识input输入子系统