阿文的天空

飘泊在北京

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

AppDomain传递对象等研究

 

AppDomain传递对象等研究》中描述了AppDomain传递对象、保存全域列表的方法;很多博友提出了应用场景的问题,本文根据个人理解描述了该问题应用的一个场景。域的加载、卸载,传递对象等实际应用的地方很多,这里姑且算做抛砖引玉吧。

在项目实际应用中经常会遇到打补丁的问题,例如360安全卫士的方法是通过下载补丁包,重新启动系统、通过某个钩子程序检测补丁是否存在,并且执行。那么在.Net环境中的方案呢?在.Net环境中最大的难题就是已经加载Assembly不能卸载,那么就会存在守护程序(补丁执行器)如何打补丁的问题。

笔者在研究AppDomain相关的程序之后,得到了通过创建AppDomain来解决守护程序问题的办法。下面进行简单的描述,并提供实现方法:

1.       实现原理

启动域:系统启动默认创建的域,该域只是一个空壳,仅仅负责创建控制域

控制域:负责实现域的启动、卸载和补丁

实现域:系统真正运行的域

2.       控制域和实现域的实现

通过上一篇文章,我们已经知道了如何获取域的实例,下面的方法我们封装了控制域和实现域的get属性。

控制域的获取:

       

 1        public AppDomain ControlDomain
 2        {
 3            get
 4            {
 5                DomainList _domainlist = LoadDomainList();
 6                if (_domainlist.AllAppDomain.ContainsKey(CONTROL_DOMAIN_DATA_FLAG))
 7                    return _domainlist.AllAppDomain[CONTROL_DOMAIN_DATA_FLAG];
 8                else
 9                    return CreateOrLoadDomain(CONTROL_DOMAIN_DATA_FLAG);
10            }

11        }

     实现域的获取:

     

 1        public AppDomain ImplementDomain
 2        {
 3            get
 4            {
 5                DomainList _domainlist = LoadDomainList();
 6                if (_domainlist.AllAppDomain.ContainsKey(IMPLEMENT_DOMAIN_DATA_FLAG))
 7                    return _domainlist.AllAppDomain[IMPLEMENT_DOMAIN_DATA_FLAG];
 8                else
 9                    return CreateOrLoadDomain(IMPLEMENT_DOMAIN_DATA_FLAG);
10            }

11        }

 

3.       控制域操作的简单实现

在控制域中简单的实现了对实现域的创建、卸载、执行补丁三个简单操作,创建方法如下:

 

Code

 

 

 

实现域的卸载

 

1        public static void Stop()
2        {
3            Console.WriteLine("Control domain stop");
4            DomainUtil _domainutil = new DomainUtil();
5            AppDomain _implementDomain = _domainutil.ImplementDomain;
6            _domainutil.UnloadDomain(_implementDomain, _implementDomain.FriendlyName);
7        }

 

执行补丁,其中类ImpTest.dll在实现域中是被加载的

 

1        public static void ExecPack()
2        {
3            Console.WriteLine("Exec Pack");
4            File.Copy(Path.Combine(PACKPATH, "ImpTest.dll"), Path.Combine(Environment.CurrentDirectory, "ImpTest.dll"),true);
5        }
 

 

4.       系统的简单测试

控制域和实现域均实现之后就可以进行测试了,测试方法如下:

 

 

 1                DomainUtil _domainutil = new DomainUtil();
 2                AppDomain _controldomain = _domainutil.ControlDomain;
 3                _controldomain.DoCallBack(new CrossAppDomainDelegate(ControlDomainUtil.Run));
 4
 5                Thread.Sleep(10 * 1000);
 6                _controldomain.DoCallBack(new CrossAppDomainDelegate(ControlDomainUtil.Stop));
 7
 8                Thread.Sleep(10 * 1000);
 9                _controldomain.DoCallBack(new CrossAppDomainDelegate(ControlDomainUtil.ExecPack));
10
11                Thread.Sleep(10 * 1000);
12                _controldomain.DoCallBack(new CrossAppDomainDelegate(ControlDomainUtil.Run));

运行结果如下: 

通过上面的方法,我们简单的实现自动打补丁,基本上解决了守护程序的问题;当然上面的方法仍然存在守护程序的问题,但笔者认为控制域的实现较为简单,逻辑也不复杂,只要发布版本之前精心测试一般不会存在补丁问题。

posted on 2009-01-09 12:08  lisw  阅读(1791)  评论(1)    收藏  举报