欢迎来到.net学习网

欢迎联系站长一起更新本网站!QQ:879621940

您当前所在位置:首页 »  .NET本质论第一卷:公共语言运行库教程 » 正文

本教程章节列表

对象和上下文(二)

创建时间:2013年03月14日 23:01  阅读次数:(5289)
分享到:
上下文属性不同于简单的SetData和GetData,当一个上下文被首次创建时,上下文属性便被建立了。像传统字段一样,上下文属性是唯一命名的,并且在创建时被绑定到个上下文。像字段的是,上下文属性与上下文在其整个生存期内都是并存的,正如我们在下一节将看到的,上下文属性也有在代理和上下文绑定对象之间注入消息接收器的机会,这种能力被证明是其存在的主要原因。

上下文特性(context Attribute)在创建时将上下文属性添加到上下文中。上下文特性(context Attribute)是支持IContextAttribute接口的自定义特性:
namespace System.Runtime.Remoting.Contexts{
 public interface ICOntextAttribute{
  bool IsContextOK(Context ctx,IconstructioonCallMessage ctor);
  void GetPropertiesPorNewContext(IconstructionCallMessage ctor);
}
}

当一个newobj操作码在一个上下文绑定的类型上执行时,CLR将枚举该类型的所有特性,并查找上下文特性。当它找到上下文特性时,CLR就给出当前上下文和一个消息,这个消息表示对每个上下文的IsContextOK方法的构造调用。上下文特性期望查看当前上下文,井次定该上下文是否合适。它所做的决定与每个特性相关。如果当前上下文是可接受的(acceptable),那么,上下文特性将返回true。如果当前上下文是不合格的,上下文特性将返回false,表明CLR必须为这个新对象创建一个新的上下文。

如果所有上下文特性的IsContext0K都返回true,那么,CLR将把这个新对象绑定到当前上下文。如果至少有一个上下文特性返回false,CLR将把这个新对象绑定到一个新的上下文。为保证这个新的上下文能被正确地初始化,CLR将对该类型的上下文特性做第一次遍历,询问它们中的每一个,以提供它所希望被绑定到新上下文的任何上下文特性。这是通过
GetPropertiesPorNewContext完成的。

在讨论这一点时,我们给出了一个例子。这里,考虑本章早先提出的线程优先级代理。我们可以使用上下文基础架构相当简单地重构那个代理.如果引用同样的优先级进行对象间的相互调用,那么,我们更愿意避免做两次调整(adjustment),而不是在每一个代理中简单地强制注入我们的截获代码.为了实现这个目的,我们将添加一个包含优先级设置的上下文属性,这个优先级设置被用于那个上下文中的所有对象。这将把应用程序分成优先级域(priority domain),在一个特定优先级域中的所有对象都共享同一个优先级,如图7.10所示。
线程优先级作为一个上下文属性

我们的上下文属性将相当简单,因为它只需要一个公有属性,那就是线程优先级:
using System.Runtime.Remoting.Contexts;
using System.Threading;

public class PriorityProperty:IcontextProperty{
ThreadPriority level;
public ThreadPriority Level{get{return level;}}
internal PriorityProperty(ThreadPriority level)
{this.level=level;}

//IcontextProperty成员
public string Name{get{return “ThreadPriority”}}
public boolIsNewContextOK(Context ctx){
return true;
}

public void Freeze(Context ctx){}
}

为了提供一种注入上下文属性的方式,我们需要定义一个支持它的上下文特性:
using System.Runtime.Remoting.Contexts;
using System.Threading;
using System;

[AttributeUsage(AttributeTaragets.Class)]
public class PriorityAttribute:Attribute,IcontextAttribute{
ThreadPriority level;
internal PriorityAttribute(ThreadPriority level)
{this.level=level;}

//IcontextProperty成员
public bool IsContextOK(Context current,IconstructionCallMessage ctor){
//我们的属性必须存在!
object prop=current.GetProperty(“ThreadPriority”);
if(prop==null) return false;
//并且它的级别必须匹配这个特表示的级别
PriorityProperty pp=(PriorityProperty)prop;
return pp.Level=this.Level;
}

public void GetPropertiesForNewContext(IconstructionCallMessage ctor){
//创建新的属性
IcontextProperty prop=new PriorityProperty(level);
//用构造函数关联属性
ctor.ContextProperties.Add(prop);
}
}

IsContextOK方法在当前的上下文中检查上下文属性的存在性。如果上下文属性不存在,我们将丢弃当前的上下文,强制CLR为新对象创建一个新的上下文。相似地,如果我们的上下文属性在当前的上下文中存在,但其优先级与我们的特性所需耍的不同,那么,我们仍然会丢弃当前上下文。这两个测试保证所有具有一个特定上下文的对象,都有相同的线程优先级。此外,它还允许两个或多个优先级需求相同的对象共享同一个上下文。这降低了资源消耗,并加快了上下文中的方法调用,从而提高了程序的整体性能。

上下文特性GetPropertiesForNewContext只是简单地创建了一个新的上下文属性,并且,使用构造调用消息与之关联。当CLR分配对象时,它也将分配一个新的上下文,并从构造调用消息的ContextProperties中初始化它的上下文属性。

当上下文属性和特性都就位后,我们就可以通过编写下面的代码来使用它:
[Priority(ThreadPriority.Highest)]
public class MyCalc5:ContextBoundObject,Icalculator{
public double Add(double x,double y){
//获取这个对象的上下文
Context here=Thread.CurrentContext ;
//提取优先级属性
IcontextProperty p=here.GetProperty("ThreadPriority");
PriorityProperty pp=(PriorityProperty)p;
//保证优先级级别被正确地设置!
Debug.Assert(pp.Level==ThreadPriority.Highest);
}
}

注意,这段代码依赖于上下文属性被正确地初始化。然而,截止目前我们所讨论的实现,对CLR来说,还不能对线程优先级做实际的调整,有关这方向的内容是下一节,也是本章最后一节的主题。
来源:.net学习网
说明:所有来源为 .net学习网的文章均为原创,如有转载,请在转载处标注本页地址,谢谢!
【编辑:Wyf】

打赏

取消

感谢您的支持,我会做的更好!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

最新评论

共有评论0条
  • 暂无任何评论,请留下您对本文章的看法,共同参入讨论!
发表评论:
留言人:
内  容:
请输入问题 84+88=? 的结果(结果是:172)
结  果: