程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 《WCF技術內幕》30:第2部分_第5章_消息:復制消息、消息清理和本章小結

《WCF技術內幕》30:第2部分_第5章_消息:復制消息、消息清理和本章小結

編輯:關於.NET

復制消息

有時候需要從現有的一個消息實例創建一個緩存模式的消息拷貝。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框架程序設計(修訂版)》。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved