在開始了解上下文之前,先來復習下.NET的應用程序的邏輯結構。通常情況下,一個進程只能運行一個應用程序。但在.NET環境下,一個進程可以運行多個應用程序,而這里的應用程序則以應用程序域划分,同一個應用程序或者程序集可以加載到同一進程的不同應用程序域中去。
上圖中沒有標識出的是線程,線程和應用程序域並不是簡單的一對一,或者一對多的關系。在一個應用程序域中可以有幾個線程存在,而一個線程也可以跨多 個應用程序域訪問資源(但一定時間內,每個線程是在應用程序域中執行的)。這里討論的重點不在線程和應用程序域的關系,因此可以簡單的認為兩者平級,示例 圖也不用標出來了。
因此應用程序域示意圖如下:
與上下文相關的類有兩個:
ContextBoundObject類
任何一個需要應用上下文同步機制類的父類,繼承自此類的子類實例稱為上下文綁定對象,而通常的類實例稱為上下文靈活對象。上下文綁定的對象永遠在其上下文中執行。
ContextAttribute類
MSDN定義:ContextAttribute 類是所有上下文屬性的根。簡單 Context 類屬性 (Property) 可以用 ContextAttribute 類中的上下文屬性 (Attribute) 和上下文屬性 (Property) 從該類中派生。對於更為專用或更復雜的需要,上下文屬性 (Attribute) 可以從 ContextAttribute 派生,並且上下文屬性 (Property) 可以拆分為一個獨立的類。
本文的示例只用到.NET自帶的Synchronization類。
下面就用示例來說明上下文與具體對象的關系及應用。
1、首先定義一個普通(上下文靈活的)類
- class ObjectClass
- {
- private string m_Name = string.Empty;
- public ObjectClass(string name)
- {
- m_Name = name;
- //獲取當前上下文信息
- Context context = Thread.CurrentContext;
- Console.WriteLine("{0} in context {1}", m_Name, context.ContextID);
- //輸出上下文的所有屬性名稱
- foreach (IContextProperty property in context.ContextProperties)
- {
- Console.WriteLine("\tContext Propery: {0}", property.Name);
- }
- Console.WriteLine();
- }
- }
2、再定義一個上下文綁定的類
- //此類將加載到一個同步上下文中
- [Synchronization]
- class ObjectClassSyn : ContextBoundObject
- {
- private string m_Name = string.Empty;
- public ObjectClassSyn(string name)
- {
- m_Name = name;
- //獲取當前上下文信息
- Context context = Thread.CurrentContext;
- Console.WriteLine("{0} in context {1}", m_Name, context.ContextID);
- //輸出上下文的所有屬性名稱
- foreach (IContextProperty property in context.ContextProperties)
- {
- Console.WriteLine("\tContext Propery: {0}", property.Name);
- }
- Console.WriteLine();
- }
- }
3、在Main函數中實例化類代碼如下:
- static void Main(string[] args)
- {
- ObjectClass objectOne = new ObjectClass("Object 1");
- ObjectClass objectTwo = new ObjectClass("Object 2");
- ObjectClassSyn objectSynOne = new ObjectClassSyn("Syn Mark Object 1");
- ObjectClassSyn objectSynTwo = new ObjectClassSyn("Syn Mark Object 2");
- Console.ReadLine();
- }
4、輸出結果如下:
從結果中我們可以看出,普通的對象會創建在默認的上下文中,在這里該上下文的編號為0。而后面的兩個上下文綁定的對象則分別創建在上下文1和上下文2中,到這里很自然的會想到,什么樣的情況下兩個對象才會在同一個非默認上下文中的呢,通過修改剛才的代碼可以得到結論。
1、剛才的兩個類都分別加上以下兩個函數
- public ObjectClass GetNormalObject(string name)
- {
- return new ObjectClass(name);
- }
- public ObjectClassSyn GetSynObject(string name)
- {
- return new ObjectClassSyn(name);
- }
2、Main函數添加兩個對象,代碼修改如下
- static void Main(string[] args)
- {
- ObjectClass objectOne = new ObjectClass("Object 1");
- ObjectClass objectTwo = new ObjectClass("Object 2");
- ObjectClassSyn objectSynOne = new ObjectClassSyn("Syn Mark Object 1");
- ObjectClassSyn objectSynTwo = new ObjectClassSyn("Syn Mark Object 2");
- ObjectClass objectThree = objectOne.GetNormalObject("Object 3");
- ObjectClassSyn objectSynThree = objectOne.GetSynObject("Syn Mark Object 3");
- ObjectClass objectFour = objectSynOne.GetNormalObject("Object 4");
- ObjectClassSyn objectSynFour = objectSynOne.GetSynObject("Syn Mark Object 4");
- Console.ReadLine();
- }
3、運行結果
前四個對象的輸出結果就不貼出來了,和前面一樣,重點關注后四個。
從結果可見:在默認上下文中創建的普通(上下文靈活的)對象,其上下文也是默認上下文0,而在默認上下文中創建的上下文綁定對象,其上下文則是不同於默認和已創建的上下文(0/1/2號上下文)的3號上下文。
而后兩個結果中,不管是上下文靈活的對象還是上下文綁定的對象創建,只要他們是在非默認的上下文中創建的,那他們的上下文就和創建時所在的上下文相同。
以上就是個人對上下文在.NET程序中的定義的淺見。
注:以SynchronizatonAttribute來同步上下文綁定對象時,會創建等待句柄和自動重置事件,這些內容可能不會被垃圾回收機制處理,所以盡量不要將此同步機制應用到短時間內大量產生的對象上。
原文鏈接:http://blog.csdn.net/shyc1922/article/details/6876412