《WCF技术内幕》翻译30:第2部分_第5章_消息:复制消息、消息清理和本章小结

Posted on 2009-12-20 20:05 Frank Xu Lei 阅读(247) 评论(1)   编辑 收藏 网摘 所属分类: 《WCF技术内幕》翻译, SOA and EAI

Copying Messages

复制消息

Message Cleanup

消息清理

Summary

本章小结

 

复制消息


有时候需要从现有的一个消息实例创建一个缓存模式的消息拷贝。Message类型定义了实现此目的的实例方法:

public MessageBuffer CreateBufferedCopy(Int32 maxBufferSize) { ... }

创建Message的拷贝还是相当简单的,但是这会带来消息内部状态的改变。如果使用不当,这个状态改变会给我们要复制的消息对象带来一些问题。当调用CreateBufferedCopy方法时,新消息的state属性必须是MessageState.Created。如果设置为其它状态,此方法就会抛出一个InvalidOperationException异常。直到CreateBufferedCopy返回结果,原调用实例的状态才会变为MessageState.Copied。如果此方法调用成功,则会返回一个System.ServiceModel. Channels.MessageBuffer类型的实例。MessageBuffer定义了一个实例方法CreateMessage,它会返回一个Message类型实例。这个实例的状态会是Message.Created。下面代码演示了如何复制一个消息:

Message msg = Message.CreateMessage(MessageVersion.Default,

                                    "urn:SomeAction",

                                    "Something in the body");

 

Console.WriteLine("Starting Message state: {0}/n", msg.State);

Console.WriteLine("Message:/n{0}/n", msg.ToString());

 

MessageBuffer buffer = msg.CreateBufferedCopy(Int32.MaxValue);

Console.WriteLine("Message state after copy: {0}/n", msg.State);

Message msgNew = buffer.CreateMessage();

Console.WriteLine("New Message State: {0}/n",msgNew.State);

Console.WriteLine("New Message:/n{0}/n", msgNew.ToString());

运行代码,输入结果如下:

Starting Message state: Created

Message:

<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing"

 xmlns:s="http://www.w3.org/2003/05/soap-envelope">

 <s:Header>

    <a:Action s:mustUnderstand="1">urn:SomeAction</a:Action>

 </s:Header>

 <s:Body>

    <string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">

      Something in the body</string>

 </s:Body>

</s:Envelope>

 

Message state after copy: Copied

New Message State: Created

New Message:

<s:Envelope xmlns:a=http://www.w3.org/2005/08/addressing

 xmlns:s="http://www.w3.org/2003/05/soap-envelope">

 <s:Header>

    <a:Action s:mustUnderstand="1">urn:SomeAction</a:Action>

 </s:Header>

 <s:Body>

    <string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">

      Something in the body

    </string>

 </s:Body>

</s:Envelope>

注意调用CreateBufferedCopy方法之后Message状态和新的Message的状态。CreateBufferedCopy的作用有限,消息的状态改变也是局限于消息复制的过程里。但是此功能也非常有用,在多消息参与者的场景中,像PeerChannel(对等通道)。在PeerChannel里,一个消息对象会被复制多次,并且这些消息拷贝会被发送到网格里不同节点上。

消息清理

Message类型实现了IDisposable接口,并且定义了一个Close方法。架构设计的一个曲折之处在于,Message实现了的Dispose成员,因此这可以阻止直接使用Message类型。调用Dispose方法需要先把Message对象转换为一个IDisposable对象,然后在通过引用调用Dispose方法。更复杂是,这个曲折之处是Close被定义为公开的方法。本质上,你调用Message对象的Close方法,但你不能直接调用Dispose方法。内部来讲,Dispose方法调用了Close方法,所以作用一样,你也可以把Message的实例化放在C# using语句中。

 

备注:我个人认为,Message 类型对于IDisposable接口的实现有些不恰当。我知道的所有的标准,包括Framework设计规范,规定了接口会很少会被清楚地实现,另外也没有那个标准接受一个Close方法,而没有一个相似的可见的Dispose方法。尽管这是为了避免开发人员混淆Close/Dispose,我认为Message使得问题更加糟糕,而不是更好。开发人员希望在类型上看到一个Dispose方法,有时候也希望看到Close方法。在Microsoft .NET Framework,我还没看到别的类型,只暴露Close,而去隐藏掉Dispose的【老徐备注1】

本章小结

Message类型包含的内容远不止我们想象的那么简单。Message是WCF里一个丰富的类型。尽管在很多WCF程序里看不到Message类型,但是它还是存在的,并且它是WCF通信的基本单位。因为其在WCF中的核心地位,我认为理解Message是理解整个WCF的关键所在。在这一章里,我看到多种创建Message对象的方法;如何序列化、编码、解码和反序列化Message对象;如何使用消息头块;等等。提醒一下,在我们学习WCF里不同层次的时候,重要的是要记住这些层次是相当繁忙的,它们会在幕后完成着本章里所描述的工作。

 【老徐备注】

1.也有别的类型只暴露Close,而去隐藏掉Dispose的。但是比较少见,确实不是一个好的设计原则。另外关于.NET垃圾回收机制,大家可以看看Jeffrey Rich的《Microsoft .NET框架程序设计(修订版)》。

 


 

老徐的博客
【作      者】:Frank Xu Lei
【地      址】:http://www.cnblogs.com/frank_xl/
【中文论坛】:微软WCF中文技术论坛
【英文论坛】:微软WCF英文技术论坛

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值