天天看点

细说进程、应用程序域与上下文之间的关系(二)—— 应用程序域

目录

<a target="_blank" href="http://blog.51cto.com/2689556/836719">一、进程的概念与作用</a>

<a target="_blank" href="http://blog.51cto.com/2689556/836724">二、应用程序域</a>

<a target="_blank" href="http://blog.51cto.com/2689556/836728">三、深入了解.NET上下文</a>

<a target="_blank" href="http://blog.51cto.com/2689556/836740">四、进程应用程序域与线程的关系</a>

二、应用程序域

使用.NET建立的可执行程序 *.exe,并没有直接承载到进程当中,而是承载到应用程序域(AppDomain)当中。应用程序域是.NET引入的一个新概念,它比进程所占用的资源要少,可以被看作是一个轻量级的进程。

在一个进程中可以包含多个应用程序域,一个应用程序域可以装载一个可执行程序(*.exe)或者多个程序集(*.dll)。这样可以使应用程序域之间实现深度隔离,即使进程中的某个应用程序域出现错误,也不会影响其他应用程序域的正常运作。

当一个程序集同时被多个应用程序域调用时,会出现两种情况:

第一种情况:CLR分别为不同的应用程序域加载此程序集。

第二种情况:CLR把此程序集加载到所有的应用程序域之外,并实现程序集共享,此情况比较特殊,被称作为Domain Neutral。

<a></a>

2.1 AppDomain的属性与方法

在System命名空间当中就存在AppDomain类,用管理应用程序域。下面是AppDomain类的常用属性:

属性

说明

ActivationContext

获取当前应用程序域的激活上下文。

ApplicationIdentity

获得应用程序域中的应用程序标识。

BaseDirectory

获取基目录。

CurrentDomain

获取当前 Thread 的当前应用程序域。

Id

获得一个整数,该整数唯一标识进程中的应用程序域。

RelativeSearchPath

获取相对于基目录的路径,在此程序集冲突解决程序应探测专用程序集。

SetupInformation

获取此实例的应用程序域配置信息。

表2.0

AppDomain类中有多个方法,可以用于创建一个新的应用程序域,或者执行应用程序域中的应用程序。

方法

CreateDomain

创建新的应用程序域。

CreateInstance

创建在指定程序集中定义的指定类型的新实例。

CreateInstanceFrom

创建在指定程序集文件中定义的指定类型的新实例。

DoCallBack

在另一个应用程序域中执行代码,该应用程序域由指定的委托标识。

ExecuteAssembly

执行指定文件中包含的程序集。

ExecuteAssemblyByName

执行程序集。

GetAssemblies

获取已加载到此应用程序域的执行上下文中的程序集。

GetCurrentThreadId

获取当前线程标识符。

GetData

为指定名称获取存储在当前应用程序域中的值。

IsDefaultAppDomain

返回一个值,指示应用程序域是否是进程的默认应用程序域。

SetData

为应用程序域属性分配值。

Load

将 Assembly 加载到此应用程序域中。

Unload

卸载指定的应用程序域。

表2.1

AppDomain类中有多个事件,用于管理应用程序域生命周期中的不同部分。

事件

AssemblyLoad

在加载程序集时发生。

AssemblyResolve

在对程序集的解析失败时发生。

DomainUnload

在即将卸载 AppDomain 时发生。

ProcessExit

当默认应用程序域的父进程存在时发生。

ReflectionOnlyAssemblyResolve

当程序集的解析在只反射上下文中失败时发生。

ResourceResolve

当资源解析因资源不是程序集中的有效链接资源或嵌入资源而失败时发生。

TypeResolve

在对类型的解析失败时发生。

UnhandledException

当某个异常未被捕获时出现。

表2.2

下面将举例详细介绍一下AppDomain的使用方式

2.2 在AppDomain中加载程序集

由表2.1中可以看到,通过CreateDomain方法可以建立一个新的应用程序域。

下面的例子将使用CreateDomain建立一个应用程序域,并使用Load方法加载程序集Model.dll。最后使用GetAssemblies方法,列举此应用程序域中的所有程序集。

运行结果

<a target="_blank" href="http://blog.51cto.com/attachment/201204/160728978.jpg"></a>

注意:当加载程序集后,就无法把它从AppDomain中卸载,只能把整个AppDomain卸载。

当需要在AppDomain加载可执行程序时,可以使用ExecuteAssembly方法。

AppDomain.ExecuteAssembly("Example.exe");

2.3 卸载AppDomain

通过Unload可以卸载AppDomain,在AppDomain卸载时将会触发DomainUnload事件。

下面的例子中,将会使用 CreateDomain建立一个名为NewAppDomain的应用程序域。然后建立AssemblyLoad的事件处理方法,在程序集加载时显示程序 集的信息。最后建立DomainUnload事件处理方法,在AppDomain卸载时显示卸载信息。

<a target="_blank" href="http://blog.51cto.com/attachment/201204/160745470.jpg"></a>

2.4 在AppDomain中建立程序集中指定类的对象

使用CreateInstance方法,能建立程序集中指定类的对像。但使用此方法将返回一个ObjectHandle对象,若要将此值转化为原类型,可调用Unwrap方法。

下面例子会建立Model.dll程序集中的Model.Person对象。

继续阅读