程序员可以通过System.AppDomain类型访问AppDomain。示例8.1为System.AppDomain公共签名的子集。这个类型最为重要的成员是CurrentDomain静态属性。这个属性只是简单地提取存储在硬线程的TLS中的AppDomain引用。有意思的是,你可以通过Thread.CurrentThroad属性,从硬线程的TLS中提取当前的软线程对象。
在引用AppDomain之后,便可以做许多事情。每一个AppDomain有自己的环境属性集,可以通过SetData和GetData方法访问。这些属性类似于OS进程中的环境变量。不同于进程环境变量的是:这些属性的作用域为特定的AppDomain。它们的功能与静态字段等价,但不同于静态字段的是,它们在每个程序集或者程序集版本中都不是重复的,因而在存在多个版本的情形下,可以用它们取代静态字段。
AppDomain的创建和清除可以通过编程实现,尽管这一般由宿主环境处理,如ASP.NET,应用程序同样能够访问这些实用部件.生成新的AppDomain。AppDomdin.createDomain方法在当前进程中创建一个新的AppDomain,并返回新的AppDomain引用。这个域将一直驻留在内存,直到调用AppDomain.Unload将其移出内存。当创建一个AppDomain后,便可以使用一系列技术强制它加载和执行代码,其中,最直接的方式就是使用AppDomain.ExecuteAssembly方法。
AppDomain.ExecuteAssemly方法将目标AppDomain加载到程序集中,并且执行其主入口点。在父AppDomain中,ExecuteAssembly方法不会加载或者初始化指定的程序集;准确地说,ExecuteAssembly方法先将AppDomain转化为子域。如果指定的程序集调用AppDomain
CurrentDoamin方法,它将获取于AppDomain对象。如果指定的程序集使用与父程序相同的任何程序集,则子AppDomain将加载它自己独立的类型与模块拷贝,包括它自己的静态字段集合。
示例8.2是关于ExecuteAssembly方法的例子。ExecuteAssernbly方法是一个同步的例程,这意味着调用者将被阻塞,直到子程序的Main方法把控制权交还运行时。如果期望非阻塞的执行,则应使用第6章介绍的异步方法调用机制。
示例8.2 生成新的应用程序
using System;
public class MyApp{
public static int Main(string[] argv)
{
//创建域
AppDomain child=AppDomain.CreateDomain(“childapp”);
//执行yourapp.exe
int r=child.ExecuteAssembl(“yourapp.exe”,null,argv);
//卸载域
AppDomain.Unload(child);
///返回结果
return r;
}
}
在AppDomain中还可以插入任意代码。AppDomain.DoCallBack方法允许你在一个共型上指定一个方法,它将在外部域中执行。这个指定方法必须是静态的,并且它的签名与CrossAppDomainDelagate签名匹配。此外,为了执行这段代码,将不得不加载外部AppDomain中的指定方法的类型、模块和程序集。如果指定方法需要在AppDomain之间共享信息,那么, 它可以在外部AppDomain上使用SetData和GetData方法。示例8.3展示了这种方式。