天天看點

細說程序、應用程式域與上下文之間的關系(二)—— 應用程式域

目錄

<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對象。

繼續閱讀