在开始了解上下文之前,先来复习下.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来同步上下文绑定对象时,会创建等待句柄和自动重置事件,这些内容可能不会被垃圾回收机制处理,所以尽量不要将此同步机制应用到短时间内大量产生的对象上。
————————————————
版权声明:本文为CSDN博主「一尘晓灰」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/shyc1922/article/details/6876412

