欢迎来到.net学习网

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

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

本教程章节列表

消息过程(回顾一)

创建时间:2013年03月07日 14:33  阅读次数:(4777)
分享到:
前一节阐述了自定义代理如何在透明代理和堆栈生成器接收器之间对方法调用进行预处理和后处理。如果你想要插入多于一级( stage)的预处理和后处理,那将是什么呢?是的,你可简单地对代理进行分层级:然而,每一级代理都会有冗余的堆栈到消息(stack-to message)的转换,从而导致过度的性能开销,更好的解决之道是在消息层面上进行链接以处理多级代理,这样,堆栈到消息的转换在每次调用中就只有一次,而不是每次调用的每个级都发生一次。这个技术是基于消息接收器(message sink)的。为了按一般方式更容易地使用,CLR定义了
System.Runtime.Remting.Messaging.ImessageSink接口:
Namespace System.Runtime,Remoting.Mesaging{
 Public interface ImessageSink{
 ImessageSink NextSink{get;}
 Imessage SyncProcessMessage(Imessage request);
 ImessageCtrl AsyncProcessMessage(Imessage request,ImessageSink upcall);
}
}

注意NextSink属性将消息接收器模型化,并将其作为接收链(chain)中的一个链接。在大多数情况下,链中的最后一个链接将会是一个堆栈生成器接收器,它实现了IMessageSink接口。我们期望消息接收器拥有链中的下一个下游链接(downstream link)的引用,并返回其NextSink实现的引用,更重要的是,当引入的方法调用发生时,消息接收器的SyncProcessMessage方法将会被调用。消息接收器只是简单地在链中的下一个下游链接上调用SyncProcessMessage,而不是调用Remoting-Services.ExecuteMessage转发调用。因为链中的倒数第二个链接通常持有堆栈生成器接收器的引用,所以,对于SyncProccessMessage的最后调用将与对RemotingServices.ExecuteMessage的调用具有同样的效果。图7.7演示了这个过程 。
使用消息接收器进行截获

消息接收器实现通常提供一个构造函数,它接收链中的下一个下游链接, 下面的类展示了优先级代理功能的实现,它被重构(refactor)为消息接收器:
Using System.Runtime.Remoting.Messaging;
Public class PrioritySink:ImessageSink{
 Readonly ThreadPriorty p;
 Readonly ImessageSink next;

 Public PrioritySink(ThreadPriority p,ImessageSink next){
This.next=next;
This.p=p;}

Public ImessageSink NextSink{get{return next;}}

Pulbic Imessage SyncProcessMessage(Imessage request){
//第1步:调整优先级
 Thread here=Thread.CurrentThread;
 ThreadPriority old=here.Priority;
  Here.Priority=level;

//第2步:转发调用
IMessage response=next.SyncProcessMessage(request);
/第3步:恢复旧的优先级
Here.Priority=old;
//第4步:将响应消息返回给TP
 Return response; 
}
//为了清晰起见,余下部分省略
}

注意,这个SyncProcessMessage实现看起来和我们最初的PricrityProxy.invoke方法是样的(除了第二步不是这样的),我们是将消息转发给接收链中的下一个链接,而不是调用RemotingServics.ExecuteMessage方法。

刚才展示的代码片断并没有演示第三个IMessageSink方法:AsyncProcessMessace。CLR消息系统以不同的方式处理异步调用。尤其是Begininvoke请求将触发一个对AsyncProcessMessage方法的调用,而不是SyncProcessMessage方法。这些AsyncProcessMessage调用将在工作者线程上发生,而不是调用方的线程。这意味着即便是你的消息接收器要花很长时间来预处理这个调用,调用方的线程还是可以继续它的下一段工作。这说明AsyncProccssMessage在消息处理过程中保留了异步调用的风格。为此,在接收链中的每个消息接收器都被给与了预处理调用的机会,而不是后处理。如果你需要后处理,则可以使用AsyncProcessMessage的第二个参数构建一个答复链( reply chain),处理调用的结果。当堆栈生成器接收器的AsyncProcessMessage实现已经完成了分发调用后,它将发送响应消息给答复链。因为答复链被反向构造,所以,后处理的步骤将以与预处理步骤相反的顺序运行(这是同步处理的工作方式)。图7.8演示了整个分发过程。
消息处理与异步调用

到目前为止给出的所有机制,其消息接收器之间通信的惟一方式是消息。这些消息的类型和内容是根据调用方原始调用的方法决定的。对于消息接收器来说,在消息中附带额外的数据经常是很有用的.例如,允许消息接收器发送额外的信息到该接收链中的另一个接收器,或者更有趣的是,将额外的信息传递给调用方或者被调用方。通过调用上下文(call context)可以向消息添加额外的信息。

请求和响应两者都有调用上下文( call context)属性,它通过Imethod Message.LogicalCallContext属性公开。调用上下文是一个每调用(percall)的属性包,它允许你使用唯一的命名插槽(slot)关联任意对象。 例如,考虑下面的SyncProcessMessage实现:
Public Imessage SyncProcessMessage(Imessage request){
ImethodMessage method=(IMethodMessage)request;
Method.LogicalCallConetext.SetData(“myKey”,52);
Return next.SyncProcessMessage(request);
}
鍕婳@b:y "}_hVAQ笅豐蠎珗\O:NsQT€剉pe膥Yt蟢蛓 z
来源:.net学习网
说明:所有来源为 .net学习网的文章均为原创,如有转载,请在转载处标注本页地址,谢谢!
【编辑:Wyf】

打赏

取消

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

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

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

最新评论

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