首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

WCF 訊息深度解析(中):訊息狀態機與讀寫拷貝核心操作

     編輯:關於.NET

上篇介紹了訊息版本與五種建立方式,本文深入探討 Message 物件的狀態機與四大基本操作:讀、寫、拷貝、關閉。理解狀態轉換規則,是避免運行時異常、正確實作訊息檢查與記錄的基石。

一、訊息狀態機:五態流轉規則

MessageState 列舉定義五種狀態:Created、Read、Written、Copied、Closed。核心規則:

  • 唯有 Created 狀態可執行讀、寫、拷貝操作
  • 讀操作 → 狀態轉為 Read;寫操作 → Written;拷貝 → Copied
  • 任意狀態均可呼叫 Close(),轉為 Closed

Message 狀態機圖

二、訊息讀取:GetBody<T> 與 GetReaderAtBodyContents

最常用 GetBody<T>() 反序列化 Body 為強型別物件,或用 GetReaderAtBodyContents() 取得 XmlDictionaryReader 手動解析。

範例: 序列化 Customer 資料契約為訊息,再 GetBody<Customer>() 還原,驗證 Equals 為 true。

狀態限制實測: 首次讀取後狀態變 Read,再次呼叫 GetBody<T>() 將拋出 InvalidOperationException。

message.State = Read
// 第二次 GetBody 拋出異常

重複讀取導致異常

三、訊息寫入:WriteMessage / WriteBody 系列方法

Message 提供 WriteMessage、WriteBody、WriteBodyContents、WriteStartEnvelope 等方法,支援寫入 XmlWriter 或 XmlDictionaryWriter。寫入後狀態轉為 Written,同樣僅限 Created 狀態呼叫。

輔助方法 WriteMessage 示範將訊息存檔並開啟:

static void WriteMessage(Message msg, string file)
{
    using (var writer = new XmlTextWriter(file, Encoding.UTF8))
        msg.WriteMessage(writer);
    Process.Start(file);
}

四、訊息拷貝:CreateBufferedCopy 解決重複讀寫難題

實際 WCF 管線中,訊息常需同時被記錄(寫入日誌)與處理(反序列化)。直接讀寫會改變狀態導致後續失效。解決方案:CreateBufferedCopy(maxBufferSize) 產生 MessageBuffer(記憶體緩衝),原訊息狀態轉 Copied;再透過 buffer.CreateMessage() 產生新訊息(狀態 Created),可重複讀寫。

var buffer = msg.CreateBufferedCopy(int.MaxValue);
msg = buffer.CreateMessage(); // 新訊息,可讀
var c1 = msg.GetBody<Customer>();
msg = buffer.CreateMessage(); // 另一新訊息,可再讀
var c2 = msg.GetBody<Customer>(); // 成功,無異常

此機制是 WCF 訊息檢查器、記錄擴展正常運作的基礎。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved