AppDomain传递对象等研究 续
在《AppDomain传递对象等研究》中描述了AppDomain传递对象、保存全域列表的方法;很多博友提出了应用场景的问题,本文根据个人理解描述了该问题应用的一个场景。域的加载、卸载,传递对象等实际应用的地方很多,这里姑且算做抛砖引玉吧。
在项目实际应用中经常会遇到打补丁的问题,例如360安全卫士的方法是通过下载补丁包,重新启动系统、通过某个钩子程序检测补丁是否存在,并且执行。那么在.Net环境中的方案呢?在.Net环境中最大的难题就是已经加载Assembly不能卸载,那么就会存在守护程序(补丁执行器)如何打补丁的问题。
笔者在研究AppDomain相关的程序之后,得到了通过创建AppDomain来解决守护程序问题的办法。下面进行简单的描述,并提供实现方法:
1. 实现原理
启动域:系统启动默认创建的域,该域只是一个空壳,仅仅负责创建控制域
控制域:负责实现域的启动、卸载和补丁
实现域:系统真正运行的域
2. 控制域和实现域的实现
通过上一篇文章,我们已经知道了如何获取域的实例,下面的方法我们封装了控制域和实现域的get属性。
控制域的获取:
public AppDomain ControlDomain2
{3
get4
{5
DomainList _domainlist = LoadDomainList();6
if (_domainlist.AllAppDomain.ContainsKey(CONTROL_DOMAIN_DATA_FLAG))7
return _domainlist.AllAppDomain[CONTROL_DOMAIN_DATA_FLAG];8
else9
return CreateOrLoadDomain(CONTROL_DOMAIN_DATA_FLAG);10
}11
}实现域的获取:
public AppDomain ImplementDomain2
{3
get4
{5
DomainList _domainlist = LoadDomainList();6
if (_domainlist.AllAppDomain.ContainsKey(IMPLEMENT_DOMAIN_DATA_FLAG))7
return _domainlist.AllAppDomain[IMPLEMENT_DOMAIN_DATA_FLAG];8
else9
return CreateOrLoadDomain(IMPLEMENT_DOMAIN_DATA_FLAG);10
}11
}
3. 控制域操作的简单实现
在控制域中简单的实现了对实现域的创建、卸载、执行补丁三个简单操作,创建方法如下:
实现域的卸载
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在实现域中是被加载的
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. 系统的简单测试
控制域和实现域均实现之后就可以进行测试了,测试方法如下:
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));运行结果如下:
通过上面的方法,我们简单的实现自动打补丁,基本上解决了守护程序的问题;当然上面的方法仍然存在守护程序的问题,但笔者认为控制域的实现较为简单,逻辑也不复杂,只要发布版本之前精心测试一般不会存在补丁问题。

浙公网安备 33010602011771号