参考 C#.Net 如何动态加载与卸载程序集(.dll或者.exe)0-------通过应用程序域AppDomain加载和卸载程序集 - 龙骑科技 - 博客园 (cnblogs.com)
大概意思是微软的.NET运行不支持直接卸载应用程序集,因为一旦加载程序集,即使是动态加载就会给该程序集加载到当前正在运行的主线程上,如果想卸载程序集就需要停掉当前主线程,所以不能这么操作。
文章介绍为了实现动态加载和卸载,可以通过AppDomain创建子程序集,需要卸载时就卸载掉整个AppDomain,
但是不知道什么原因,在执行AppDomain加载子程序集时跟断点明明已经拿到了dll文件的程序集,但在返回的时候会报没有序列化的异常。
接下来我给我的代码运行代码贴出来看一下
首先创建Plugin1类库项目并创建One.cs文件内容如下发布出文件为Plugin1.dll文件
using System; namespace Plugin1 { [Serializable] public class One : MarshalByRefObject { public string GetName(string name) { return "输出当前名字:" + name; } } }
然后创建新的测试项目首先创建类ObjectLoader1.cs文件代码如下
1 using System; 2 using System.Collections; 3 using System.Reflection; 4 5 /// <summary> 6 /// ObjectLoader 的摘要说明 7 /// </summary> 8 public class ObjectLoader1:IDisposable 9 { 10 protected Hashtable domains = new Hashtable(); 11 public ObjectLoader1() { } 12 public object GetObject(string dllName,string typeName,object[] constructorParms) 13 { 14 AssemblyLoader al = null; 15 object o = null; 16 if (al == null) 17 { 18 AppDomainSetup setup = new AppDomainSetup(); 19 setup.ShadowCopyFiles = "true"; 20 AppDomain domain = AppDomain.CreateDomain(dllName, null, setup); 21 domains.Add(dllName, domain); 22 object[] parms = { dllName }; 23 BindingFlags bindings = BindingFlags.CreateInstance | BindingFlags.Instance | BindingFlags.Public; 24 try 25 { 26 var ww = CYQ.Data.AppConst.WebRootPath; 27 var currAssembly=Assembly.GetExecutingAssembly(); 28 al = (AssemblyLoader)domain.CreateInstanceFromAndUnwrap(currAssembly.CodeBase, "AssemblyLoader", true, bindings, null, parms, null, null); 29 } 30 catch (Exception e1) 31 { 32 throw new Exception(); 33 } 34 } 35 if (al != null) 36 { 37 o = al.GetAssembly(); 38 } 39 return o; 40 } 41 public void Unload(string dllName) 42 { 43 if (domains.ContainsKey(dllName)) 44 { 45 AppDomain domain = (AppDomain)domains[dllName]; 46 AppDomain.Unload(domain); 47 domains.Remove(dllName); 48 } 49 } 50 ~ObjectLoader1() { 51 dispose(false); 52 } 53 public void Dispose() { 54 dispose(true); 55 } 56 private void dispose(bool disposing) 57 { 58 if (disposing) 59 { 60 foreach(object o in domains.Keys) 61 { 62 string dllName = o.ToString(); 63 Unload(dllName); 64 } 65 domains.Clear(); 66 } 67 } 68 } 69 public class AssemblyLoadFailureException1 : Exception 70 { 71 public AssemblyLoadFailureException1() : base() 72 { 73 } 74 75 public override string Message 76 { 77 get 78 { 79 return "Assembly Load Failure"; 80 } 81 } 82 83 } 84 public class AssemblyLoader1 : MarshalByRefObject, IDisposable 85 { 86 private Assembly a = null; 87 public AssemblyLoader1() { } 88 public AssemblyLoader1(string fullPath) { 89 if (a == null) 90 { 91 a = Assembly.LoadFrom(fullPath); 92 } 93 } 94 ~AssemblyLoader1() { 95 dispose(false); 96 } 97 public void Dispose() 98 { 99 dispose(true); 100 } 101 private void dispose(bool disposing) 102 { 103 if (disposing) 104 { 105 a = null; 106 GC.Collect(); 107 GC.WaitForPendingFinalizers(); 108 GC.Collect(0); 109 } 110 } 111 public Assembly GetAssembly() 112 { 113 return a; 114 } 115 public Assembly LoadAssembly(string dllName) 116 { 117 try 118 { 119 a = Assembly.LoadFrom(dllName); 120 return a; 121 } 122 catch (Exception) 123 { 124 throw new AssemblyLoadFailureException1(); 125 } 126 } 127 }
然后调用代码
1 var ww = AppDomain.CurrentDomain.BaseDirectory; 2 ObjectLoader1 ol = new ObjectLoader1(); 3 var o = ol.GetObject(ww + "Plugin1.dll", "Plugin1.One", new object[] { });
断点ObjectLoader1.cs文件的37行,和ObjectLoader1.cs的113行,F10执行,会发现在执行完113行之后代码正常返回,但紧跟着回到第37行时,代码抛出异常
System.IO.FileNotFoundException:“未能加载文件或程序集“Plugin1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null”或它的某一个依赖项。系统找不到指定的
接下来就不知道如何解决了,只能搁置到这里了,如果哪位大神有解决方案希望可以告知!
标签:asp,string,AppDomain,dllName,卸载,net,null,public,加载 From: https://www.cnblogs.com/uxinxin/p/18307912