.Net 之不同AppDomin之间通讯
来源:互联网 发布:前端和java哪个工资高 编辑:程序博客网 时间:2024/06/10 19:50
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading;using System.Reflection;using System.Runtime.Remoting;namespace Marshal{ class Program { static void Main(string[] args) { // 获取一个指向应用程序域的引用 AppDomain adCallingThreadDomain = Thread.GetDomain(); // 每一个应用程序域都会被分配一个名字帮助调试 ,以下代码获取引用程序域的名字 String callingDomainName = adCallingThreadDomain.FriendlyName; // 获取应用程序域的完整名 String exeAssembly = Assembly.GetEntryAssembly().FullName; AppDomain ad2 = null; // ************************************************************************************************************ // 使用Marshal-by-Reference的方式跨域通信 Console.WriteLine("{0}Demo #1", Environment.NewLine); // 建立一个域,安全和配置均使用当前域的设置 ad2 = AppDomain.CreateDomain("AD #2", null, null); MarshalByRefType mbrt = null; // 加载Assembly到新的域,new一个对象并且返回到当前域 (实际上返回的是一个引用代理) mbrt = (MarshalByRefType)ad2.CreateInstanceAndUnwrap(exeAssembly, "Marshal.MarshalByRefType"); Console.WriteLine("Type={0}", mbrt.GetType()); // CLR 对GetType做了一些手脚,返回的是被代理数据的真实类型 // 以下代码证明我们获取的是一个代理对象 Console.WriteLine("Is proxy={0}", RemotingServices.IsTransparentProxy(mbrt)); // 我们调用了代理类的SomeMethod() , 代理类跨域访问真正的对象 mbrt.SomeMethod(); // 卸载新建的那个应用程序域 AppDomain.Unload(ad2); // mbrt refers to a valid proxy object; the proxy object refers to an invalid AppDomain try { // 再次调用代理类的SomeMethod() , 由于域已经被卸载 抛出一个异常 mbrt.SomeMethod(); Console.WriteLine("Successful call."); } catch (AppDomainUnloadedException) { Console.WriteLine("Failed call."); } // ************************************************************************************************************ // 使用Marshal-by-Value 的方式跨域通信 Console.WriteLine("{0}Demo #2", Environment.NewLine); // 新建域 ad2 = AppDomain.CreateDomain("AD #2", null, null); // 加载程序集并创建代理类 mbrt = (MarshalByRefType)ad2.CreateInstanceAndUnwrap(exeAssembly, "Marshal.MarshalByRefType"); // 该方法返回了一个值的拷贝 marshaled by value (not be reference). MarshalByValType mbvt = mbrt.MethodWithReturn(); // 证明返回值不是一个代理类 Console.WriteLine("Is proxy={0}", RemotingServices.IsTransparentProxy(mbvt)); // 查看返回值是谁创建的 Console.WriteLine("Returned object created " + mbvt.ToString()); // 卸载应用程序域 AppDomain.Unload(ad2); // 由于是值传递,那么卸载域对函数没有影响 // marshaled by value try { //不会有异常抛出 Console.WriteLine("Returned object created " + mbvt.ToString()); Console.WriteLine("Successful call."); } catch (AppDomainUnloadedException) { Console.WriteLine("Failed call."); } // ************************************************************************************************************ // non-marshalable type 跨域通信 Console.WriteLine("{0}Demo #3", Environment.NewLine); ad2 = AppDomain.CreateDomain("AD #2", null, null); mbrt = (MarshalByRefType)ad2.CreateInstanceAndUnwrap(exeAssembly, "TestConsole.MarshalByRefType"); // 没有标记为 Serializable 的类型对象 不能通过marshaled by value 跨域通信 NonMarshalableType nmt = mbrt.MethodArgAndReturn(callingDomainName); } } //即使没有标记为Serializable 也可以通过 marshaled-by-reference 的方式跨域通信 public sealed class MarshalByRefType : MarshalByRefObject { public MarshalByRefType() { Console.WriteLine("{0} ctor running in {1}", this.GetType().ToString(), Thread.GetDomain().FriendlyName); } public void SomeMethod() { Console.WriteLine("Executing in " + Thread.GetDomain().FriendlyName); } public MarshalByValType MethodWithReturn() { Console.WriteLine("Executing in " + Thread.GetDomain().FriendlyName); MarshalByValType t = new MarshalByValType(); return t; } public NonMarshalableType MethodArgAndReturn(String callingDomainName) { // NOTE: callingDomainName is [Serializable] Console.WriteLine("Calling from ‘{0}’ to ‘{1}’.", callingDomainName, Thread.GetDomain().FriendlyName); NonMarshalableType t = new NonMarshalableType(); return t; } } //只有标记为 Serializable 的类型 才能用marshaled by value 的方式跨域通信 [Serializable] public sealed class MarshalByValType : Object { private DateTime m_creationTime = DateTime.Now; // NOTE: DateTime is [Serializable] public MarshalByValType() { Console.WriteLine("{0} ctor running in {1}, Created on {2:D}", this.GetType().ToString(), Thread.GetDomain().FriendlyName, m_creationTime); } public override String ToString() {
return m_creationTime.ToLongDateString(); } } // 没有标记为 Serializable 的类型 不能用marshaled by value 的方式跨域通信 // [Serializable] public sealed class NonMarshalableType : Object { public NonMarshalableType() { Console.WriteLine("Executing in " + Thread.GetDomain().FriendlyName); } }}
显示结果为:
- .Net 之不同AppDomin之间通讯
- 两不同程序之间通讯
- 多个Activity之间通讯,不同package之间
- asp.net与javacript之间的通讯
- 使用PB编写不同应用之间的相互通讯
- MSMQ安全性及不同版本之间通讯的问题
- Liferay 用PortletSession 实现不同Liferay之间通讯
- sql建立不同服务器上的数据库之间的通讯
- 串行通讯之.NET SerialPort
- ICE学习之C# Java之间通讯
- Android开发之Activity之间的通讯
- 进程之间的通讯之共享内存
- 进程之间的通讯之管道
- UDP网间通讯(不同局域网之间通讯) UDP打洞详细过程 图文
- asp.Net不同页之间传值
- asp.Net不同页之间传值
- .NET Framework 不同版本之间区别
- 利用LocalConnection实现多个应用之间的通讯 (不同MXML之间的通信)
- Java多线程管理
- 【IPC通信】基于管道的popen和pclose函数
- android多国语言的国家代码
- HTTP-超文本传送协议
- Content Provider初谈和Android联系人信息
- .Net 之不同AppDomin之间通讯
- typedef变态用法
- MySQL操作系统和硬件优化
- webkit开发学习笔记
- JAVA架构师要求
- 在Microsoft Windows XP中使用NetMeeting
- 关于django时区设置的问题
- Project Euler problem 50
- 在div中使用innerHTML的注意事项