public NonMarshalableType MethodArgAndReturn(string callingDomainName) { Console.WriteLine("Calling from '{0}' to '{1}'.", callingDomainName, Thread.GetDomain().FriendlyName); NonMarshalableType t = new NonMarshalableType(); return(t); }
private static void Marshalling() { AppDomain adCallingThreadDomain = Thread.GetDomain(); string callingDomainName = adCallingThreadDomain.FriendlyName; Console.WriteLine("Default AppDomain's friendly name={0}", callingDomainName); string exeAssembly = Assembly.GetEntryAssembly().FullName; Console.WriteLine("Main assembly={0}", exeAssembly); AppDomain ad2 = null; Console.WriteLine("{0}Demo #1", Environment.NewLine); ad2 = AppDomain.CreateDomain("AD #2", null, null); MarshalByRefType mbrt = null; mbrt = (MarshalByRefType)ad2.CreateInstanceAndUnwrap(exeAssembly, "Chapter22.MarshalByRefType"); Console.WriteLine("Type={0}", mbrt.GetType().ToString()); Console.WriteLine("Is proxy={0}", RemotingServices.IsTransparentProxy(mbrt)); mbrt.SomeMethod(); AppDomain.Unload(ad2); try { mbrt.SomeMethod(); Console.WriteLine("Successful call."); } catch (AppDomainUnloadedException) { Console.WriteLine("Failed call."); } Console.WriteLine("{0}Deomo #2", Environment.NewLine); ad2 = AppDomain.CreateDomain("AD #2", null, null); mbrt = (MarshalByRefType)ad2.CreateInstanceAndUnwrap(exeAssembly, "Chapter22.MarshalByRefType"); MarshalByValType mbvt = mbrt.MethodWithReturn(); Console.WriteLine("Is proxy={0}", RemotingServices.IsTransparentProxy(mbvt)); Console.WriteLine("Returned object created " + mbvt.ToString()); AppDomain.Unload(ad2); try { Console.WriteLine("Returned object created " + mbvt.ToString()); } catch (AppDomainUnloadedException) { Console.WriteLine("Failed call"); } Console.WriteLine("{0}Demo #3", Environment.NewLine); ad2 = AppDomain.CreateDomain("AD #2", null, null); mbrt = (MarshalByRefType)ad2.CreateInstanceAndUnwrap(exeAssembly, "Chapter22.MarshalByRefType"); NonMarshalableType nmt = mbrt.MethodArgAndReturn(callingDomainName); Console.WriteLine("返回不可封送对象"); }
//AppDomain没有在.NET Core当中实现,需要使用.NET Framework private static void Marshalling() { //获取AppDomain引用 AppDomain adCallingThreadDomain = Thread.GetDomain(); //每个AppDomain都分配了字符串名称 string callingDomainName = adCallingThreadDomain.FriendlyName; Console.WriteLine("Defaul AppDomain friendly name = {0}", callingDomainName); //获取包含了Main的方法集 string exeAssembly = Assembly.GetEntryAssembly().FullName; Console.WriteLine("Main assembly={0}", exeAssembly); AppDomain ad2 = null; //使用Marshal-by-Reference进行通信 Console.WriteLine("{0} Demo #1", Environment.NewLine); //新建一个AppDomain,从当前的继承安全性和配置 ad2 = AppDomain.CreateDomain("AD #2", null, null); MarshalByRefType mbrt = null; //将程序集加载到新的AppDomain当中,构造一个对象,把他封装会原来的AppDomain(实际会得到到一个代理引用) mbrt = (MarshalByRefType)ad2.CreateInstanceAndUnwrap(exeAssembly, "MarshalByRefType"); Console.WriteLine("Type={0}", mbrt.GetType()); //CLR在类型上撒谎了 //证明得到的是一个代理对象的引用 Console.WriteLine("Is proxy={0}", RemotingServices.IsTransparentProxy(mbrt)); //看起来像是再MarshalByRefType上调用方法 //实际是在代理类型上调用方法 mbrt.SomeMethod(); //卸载 AppDomain.Unload(ad2); //mbrt引用一个有效的代理对象,代理对象引用一个无效的AppDomain try { mbrt.SomeMethod(); Console.WriteLine("Successful calling"); } catch (AppDomainUnloadedException) { Console.WriteLine("Failed call"); } //DEMO2: 使用Marshal-by-value进行跨AppDomain通信 Console.WriteLine("{0} Demo #2", Environment.NewLine); ad2 = AppDomain.CreateDomain("AD #2", null, null); mbrt = (MarshalByRefType)ad2.CreateInstanceAndUnwrap(exeAssembly, "MarshalByRefType"); //对象的方法返回对象的副本,按值封送 MarshalByValType mbvt = mbrt.MethodWithReturn(); //证明得到的不是一个代理对象的引用 Console.WriteLine("Is proxy={0}", RemotingServices.IsTransparentProxy(mbrt)); Console.WriteLine("Returned object created ", mbvt.ToString()); //卸载 AppDomain.Unload(ad2); //mbvt是值,卸载AppDomain没有影响 try { mbrt.SomeMethod(); Console.WriteLine("Successful calling"); } catch (AppDomainUnloadedException) { Console.WriteLine("Failed call"); } //Demo 3: 使用不可封送的类型跨AppDomain通信 ad2 = AppDomain.CreateDomain("AD #2", null, null); mbrt = (MarshalByRefType)ad2.CreateInstanceAndUnwrap(exeAssembly, "MarshalByRefType"); //对象的方法返回一个不可封送的对象,抛出异常 NonMarshalableType nmt = mbrt.MethodArgAndReturn(callingDomainName); }