近日在研究AppDomain相关的东西,对于AppDomain之间传递对象以及创建、卸载域方面有一定的心得,写出来与大家分享,如有不到之处欢迎排砖。
.net中Appdomain是个非常有用的概念,其进程级的独立性使得程序的处理有了更简洁的处理方式。我们目前项目中运用的比如远程exe的 Remoting加载和卸载、自动补丁等。这里描述一下AppDomain之间的对象传递和多个域的控制。
AppDomain传递对象等研究
近日在研究AppDomain相关的东西,对于AppDomain之间传递对象以及创建、卸载域方面有一定的心得,写出来与大家分享,如有不到之处欢迎排砖。
.net中Appdomain是个非常有用的概念,其进程级的独立性使得程序的处理有了更简洁的处理方式。我们目前项目中运用的比如远程exe的 Remoting加载和卸载、自动补丁等。这里描述一下AppDomain之间的对象传递和多个域的控制。
1. 域的传值
域的传值方式包括AppDomain的createInstance,Remoting,以及WCF等第三方媒介都可以实现。其中Remoting和WCF都需要建立端口侦听,对于企业级的应用这种方式还算是比较合适;但是也存在一定的不足,如果建立的侦听端口没有及时释放就会出问题(个人对于这类问题是比较反感的);因此在本文采用CreateInstance方式。
多个域的协同工作中,如果采用CreateInstance方式则需要,需要知道目标域的实例才可以跨域获取数据。下面的例子提供了一种域的实例的跨域全局保存的方法,程序在任何地方均可得到全部域的实例,那么跨域存储数据将迎刃而解。
2. 域的创建
本文将应用程序启动时的域称为启动域,首先创建域时封装了一个方法将启动域保存在新域中。
Code
1 AppDomain _domain = AppDomain.CreateDomain(domainFrindlyName, StartDomain.Evidence, domainSetup);
2 _domain.SetData(START_DOMAIN_DATA_FLAG, StartDomain);
启动域的获取方式如下:
Code
1 private AppDomain _startdomain = null;
2 private AppDomain StartDomain
3 {
4 get {
5 if (_startdomain == null)
6 {
7 _startdomain = AppDomain.CurrentDomain.GetData(START_DOMAIN_DATA_FLAG) as AppDomain;
8 if (_startdomain == null)
9 _startdomain = AppDomain.CurrentDomain;
10 }
11 return _startdomain;
12 }
13 }
3. 域列表的获取与保存
Code
1 public DomainList LoadDomainList()
2 {
3 RemoteDomainUtil _domainutil = StartDomain.CreateInstanceAndUnwrap("DomainUtilPrj", "DomainUtilPrj.RemoteDomainUtil") as RemoteDomainUtil;
4 if (_domainutil == null)
5 throw new Exception("Remote create instance RemoteDomainUtil error");
6 return _domainutil.RemoteLoadDomainList();
7 }
8
9 private void SetDomainList(DomainList domainList)
10 {
11 RemoteDomainUtil _domainutil = StartDomain.CreateInstanceAndUnwrap("DomainUtilPrj", "DomainUtilPrj.RemoteDomainUtil") as RemoteDomainUtil;
12 if (_domainutil == null)
13 throw new Exception("Remote create instance RemoteDomainUtil error");
14 _domainutil.RemoteSetDomainList(domainList);
15 }
Code
1 public AppDomain CreateOrLoadDomain(AppDomainSetup domainSetup, string domainFrindlyName)
2 {
3 DomainList _domainlist = LoadDomainList();
4 if (_domainlist.AllAppDomain.ContainsKey(domainFrindlyName))
5 return _domainlist[domainFrindlyName];
6
7 AppDomain _domain = AppDomain.CreateDomain(domainFrindlyName, StartDomain.Evidence, domainSetup);
8 _domain.SetData(START_DOMAIN_DATA_FLAG, StartDomain);
9
10 _domainlist.AddDomain(domainFrindlyName, _domain);
11 SetDomainList(_domainlist);
12 return _domain;
13 }
通过上面的方法我们可以在任何域中获取域列表。那么剩下的跨域传递对象将不再是难事,此处不再描述。
总结:通过以上的方式可以获取特定的域,但是跨域调用数据会加载另一个域中类库,会增加类库之间的耦合