細說進程、應用程序域與上下文之間的關係(三)—— 深入瞭解.NET上下文

目錄

一、進程的概念與作用

二、應用程序域

三、深入瞭解.NET上下文

四、進程應用程序域與線程的關係

 

三、深入瞭解.NET上下文

3.1 .NET上下文的概念

應用程序域是進程中承載程序集的邏輯分區,在應用程序域當中,存在更細粒度的用於承載.NET對象的實體,那就.NET上下文Context。
所有的.NET對象都存在於上下文當中,每個AppDomain當中至少存在一個默認上下文(context 0)。
一般不需要指定特定上下文的對象被稱爲上下文靈活對象(context-agile),建立此對象不需要特定的操作,只需要由CLR自行管理,一般這些對象都會被建立在默認上下文當中。

 

圖3.0

3.2 透明代理

在上下文的接口當中存在着一個消息接收器負責檢測攔截和處理信息,當對象是MarshalByRefObject的子類的時候,CLR將會建立透明代理,實現對象與消息之間的轉換。
應 用程序域是CLR中資源的邊界,一般情況下,應用程序域中的對象不能被外界的對象所訪問。而MarshalByRefObject 的功能就是允許在支持遠程處理的應用程序中跨應用程序域邊界訪問對象,在使用.NET Remoting遠程對象開發時經常使用到的一個父類。
此文章針對的是進程與應用程序域的作用,關於MarshalByRefObject的使用已經超越了本文的範圍,關於.NET Remoting 遠程對象開發可參考:“回顧.NET Remoting分佈式開發”

 

3.3 上下文綁定

當系統需要對象使用消息接收器機制的時候,即可使用ContextBoundObject類。ContextBoundObject繼承了MarshalByRefObject類,保證了它的子類都會通過透明代理被訪問。
在 第一節介紹過:一般類所建立的對象爲上下文靈活對象(context-agile),它們都由CLR自動管理,可存在於任意的上下文當中。而 ContextBoundObject 的子類所建立的對象只能在建立它的對應上下文中正常運行,此狀態被稱爲上下文綁定。其他對象想要訪問ContextBoundObject 的子類對象時,都只能通過代透明理來操作。

下面的例子,是上下文綁定對象與上下文靈活對象的一個對比。Example 是一個普通類,它的對象會運行在默認上下文當中。而ContextBound類繼承了ContextBoundObject,它的對象是一個上下文綁定對 象。ContextBound還有一個Synchronization特性,此特性會保證ContextBound對象被加載到一個線程安全的上下文當中 運行。另外,Context類存在ContextProperties屬性,通過此屬性可以獲取該上下文的已有信息。

 1     class Program
 2     {
 3         public class Example
 4         {
 5             public void Test()
 6             {
 7                 ContextMessage("Example Test\n");
 8             }
 9             //訪問上下文綁定對象測試
10 public void Sync(ContextBound contextBound) 11 { 12 contextBound.Test("Example call on contextBound\n"); 13 } 14 } 15 16 [Synchronization] 17 public class ContextBound:ContextBoundObject 18 { 19 public void Test(string message) 20 { 21 ContextMessage(message); 22 } 23 } 24 25 static void Main(string[] args) 26 { 27 Example example = new Example(); 28 example.Test(); 29 ContextBound contextBound = new ContextBound(); 30 contextBound.Test("ContentBound Test\n"); 31 example.Sync(contextBound); 32 Console.ReadKey(); 33 } 34 35 //顯示上下文信息
36 public static void ContextMessage(string data) 37 { 38 Context context = Thread.CurrentContext; 39 Console.WriteLine(string.Format("{0}ContextId is {1}", data, context.ContextID)); 40 foreach (var prop in context.ContextProperties) 41 Console.WriteLine(prop.Name); 42 Console.WriteLine(); 43 } 44 }

運行結果

由運行結果可以發現,example對象一般只會工作於默認上下文context 0 當中,而contextBound則會工作於線程安全的上下文 context 1當中。當example需要調用contextBound對象時,就會通過透明代理把消息直接傳遞到context 1中。
 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章