Windows CE / Mobile 設備進程間通信 (IPC) 主流方案:**MSMQ (Microsoft Message Queuing)** 支持離線存轉、事務性、跨網絡路由,是移動場景下最可靠選擇。本文詳解 CF.NET 下 `System.Messaging` 開發:隊列創建、Formatter 配置、異步接收、請求-響應模式、發布-訂閱模式完整代碼。
MessageQueue:隊列操作入口。XmlMessageFormatter:序列化器,需指定允許類型數組 `new Type[] { typeof(string), typeof(int) }`。public class MqService
{
private const string QueuePath = @".\Private$\MQServiceQueue$";
private MessageQueue _queue;
public void Init()
{
if (!MessageQueue.Exists(QueuePath))
_queue = MessageQueue.Create(QueuePath);
else
_queue = new MessageQueue(QueuePath);
_queue.Formatter = new XmlMessageFormatter(new[] { typeof(string) });
_queue.ReceiveCompleted += OnReceiveCompleted;
_queue.BeginReceive(); // 進入異步接收循環
}
private void OnReceiveCompleted(object sender, ReceiveCompletedEventArgs e)
{
try
{
var mq = (MessageQueue)sender;
var msg = mq.EndReceive(e.AsyncResult); // 結束本次接收
// 處理業務邏輯
if (msg.Body is string cmd)
{
if (cmd == "mq_request_1")
msg.ResponseQueue?.Send("mq_response_1");
else if (cmd == "mq_request_2")
msg.ResponseQueue?.Send(true);
}
}
catch (MessageQueueException ex) { /* 日誌 */ }
finally
{
// 關鍵:重新進入下一次接收
_queue.BeginReceive();
}
}
}
public class MqClient
{
private const string ServicePath = @".\Private$\MQServiceQueue$";
private const string ClientPath = @".\Private$\MQClientQueue$";
private MessageQueue _svcQueue, _cliQueue;
public void Init()
{
_svcQueue = new MessageQueue(ServicePath);
if (!MessageQueue.Exists(ClientPath))
_cliQueue = MessageQueue.Create(ClientPath);
else
_cliQueue = new MessageQueue(ClientPath);
_cliQueue.Formatter = new XmlMessageFormatter(new[] { typeof(string), typeof(bool) });
_cliQueue.ReceiveCompleted += OnClientReceive;
_cliQueue.BeginReceive();
}
public void SendRequest()
{
var msg = new Message("mq_request_1") { ResponseQueue = _cliQueue };
_cliQueue.Purge(); // 清空舊響應
_svcQueue.Send(msg);
// 同步等待響應 (含超時)
var resp = _cliQueue.Receive(TimeSpan.FromSeconds(4));
Console.WriteLine($"Response: {resp.Body}");
}
private void OnClientReceive(object sender, ReceiveCompletedEventArgs e)
{
// 異步響應處理邏輯 (如更新 UI)
_cliQueue.BeginReceive();
}
}
// 服務端維護訂閱者字典
private Dictionary<string, MessageQueue> _subscribers = new Dictionary<string, MessageQueue>();
private void OnReceiveCompleted(object sender, ReceiveCompletedEventArgs e)
{
var msg = _queue.EndReceive(e.AsyncResult);
if (msg.Body is string cmd)
{
if (cmd == "mq_register_1")
_subscribers[msg.Label] = msg.ResponseQueue; // Label 作為訂閱者標識
else if (cmd == "mq_unregister_1")
{
_subscribers[msg.Label]?.Purge();
_subscribers.Remove(msg.Label);
}
else if (cmd == "mq_notify_all")
NotifyAll(msg.Body.ToString());
}
_queue.BeginReceive();
}
private void NotifyAll(string payload)
{
foreach (var q in _subscribers.Values)
q.Send(payload);
}
客戶端發送 `mq_register_1` (Label=client1, ResponseQueue=本地隊列) 訂閱,服務端廣播遍歷字典 `Send`。
| 模式 | 適用場景 |
|---|---|
| 請求-響應 | 設備與後台服務同步調用、命令下發確認 |
| 發布-訂閱 | 實時通知、價格推送、狀態廣播、多設備協同 |
| 離線存轉 | 網絡斷續環境下數據採集、日志上傳 |
MSMQ 將 Observer 模式擴展到進程邊界之外,是移動設備可靠 IPC 的基石。