1.1 MessageQueue控件
MessageQueue控件是.NET Compact Framework 2.0提供的新控件之一。在Windows CE操作系统中没有内置“消息队列”(也称为MSMQ)。但是.NET Compact Framework 2.0为Windows CE提供了对 “消息队列”的支持。MessageQueue控件是对“消息队列”的包装,提供对“消息队列”队列的引用。MSMQ使应用程序可以跨网络与Pocket PC或桌面应用程序进行同步或异步通信。MessageQueue控件没有设计时界面。
应用程序使用MessageQueue控件将消息发送到MSMQ。MSMQ可以在设备间发送和接收应用程序消息。当网络连接建立时,MSMQ将消息传送到远程队列,而无需考虑接收消息的应用程序是否正在运行。接收应用程序可以在任何时候从其本地队列中检查消息。
表4-8列出了MessageQueue控件的主要属性。
表4-8:MessageQueue的主要属性
属性 | 说明 |
CanRead | 获取一个值,该值指示 MessageQueue 是否可读。 |
CanWrite | 获取一个值,该值指示 MessageQueue 是否可写。 |
Category | 获取或设置队列类别。 |
FormatName | 获取“消息队列”在创建队列时生成的唯一队列名。 |
Formatter | 获取或设置格式化程序,该格式化程序用于将对象序列化为从队列读取或写入队列的消息体,或者用于将从队列读取或写入队列的消息体反序列化为对象。 |
Id | 获取队列的唯一“消息队列”标识符。 |
Label | 获取或设置队列说明。 |
MachineName | 获取或设置“消息队列”队列所在的计算机的名称。 |
MaximumQueueSize | 获取或设置队列的最大容量。 |
Path | 获取或设置队列的路径。设置Path会导致MessageQueue指向新队列。 |
QueueName | 获取或设置标识队列的友好名称。 |
可以采用有三种名称对MessageQueue控件的Path属性进行设置:友好名称、FormatName或Label。友好名称由MachineName和QueueName属性定义,公共队列采用MachineName/QueueName形式表示,专用队列采用MachineName/Private$/QueueName形式表示。FormatName属性允许对消息队列进行脱机访问。除此,还可使用队列的 Label 属性设置队列的Path属性。.NET Compact Framework 2.0只支持XmlMessageFormatter,以将消息序列化至消息队列,并从消息队列反序列化消息。
表4-3列出了MessageQueue控件的主要方法。
表4-3:MessageQueue的主要方法
方法 | 说明 |
BeginPeek | 通过通知“消息队列”开始查看消息并在完成后通知事件处理程序,启动一个异步查看操作。 |
BeginReceive | 通过通知“消息队列”开始接收消息并在完成后通知事件处理程序,启动一个异步接收操作。 |
Create | 在“消息队列”服务器上的指定路径中创建新队列。 |
Delete | 删除“消息队列”服务器上的队列。 |
EndPeek | 完成指定的异步查看操作。 |
EndReceive | 完成指定的异步接收操作。 |
Equals | 确定两个Object实例是否相等。 |
Exists | 确定指定的路径中是否存在“消息队列”队列。 |
GetAllMessages | 返回位于队列中的所有消息。 |
GetPrivateQueuesByMachine | 检索指定计算机上的所有专用队列。 |
GetType | 获取当前实例的Type。 |
Peek | 返回队列中第一条消息的副本,而不从队列中移除该消息。 |
Purge | 删除队列中包含的所有消息。 |
可以在MessageQueue的构造函数中指定一个连接到现有队列资源的路径,或者在创建新队列。在调用Send(Object)、Peek或Receive之前,必须将MessageQueue控件与某个现有队列关联。此时,可操作该队列的属性,如Category和Label。
MessageQueue控件支持两种方式的消息检索:同步和异步。同步方式采用Peek和Receive方法使线程用指定的间隔时间等待新消息到达队列。异步方式的BeginPeek和BeginReceive方法允许Pocket PC应用程序在消息到达队列之前,在单独的线程中继续执行。 当创建MessageQueue控件的新实例时,并不是要创建新的“消息队列”队列,而是使用 Create(String)、Delete和Purge方法管理服务器上的队列。
与Purge方法不同,Create(String)和Delete是static成员,因此可以调用它们而无需创建 MessageQueue 类的实例。
1.1.1 创建消息队列
清单4-11演示在本地设备上创建一个名为myQueue的消息队列。
清单 4-11 创建消息队列
…… If Not System.Messaging.MessageQueue.Exists("./myQueue") Then Try ' 创建新的队列 Dim myQueue As New System.Messaging.MessageQueue("./myQueue") MsgBox("队列创建成功") Catch ex As Exception MsgBox(ex.Message) End Try Else MsgBox("队列已存在") End If ……
|
1.1.2 向队列发送消息
清单4-13演示向本地设备上的myQueue队列发送消息。消息内容可以根据实际需要进行自定义,这里自定义一个可序列化的order类,消息每次向队列发送一个order类实例。清单4-12演示order类的定义。
清单 4-12 order类定义
Public Class Order Dim ID As Integer Dim DTime As DateTime Public Property orderID() As Integer Get Return Me.ID End Get Set(ByVal value As Integer) Me.ID = value End Set End Property Public Property orderTime() As DateTime Get Return Me.DTime End Get Set(ByVal value As DateTime) Me.DTime = value End Set End Property End Class |
清单 4-13 向队列发送消息
…… ' 创建消息内容 Dim sendOrder As New Order() Dim myQueue As New System.Messaging.MessageQueue("./myQueue")
sendOrder.orderID = 23123 sendOrder.orderTime = DateTime.Now Try ' 发送消息 myQueue.Send(sendOrder) MsgBox("消息发送成功") Catch ex As Exception MsgBox(ex.Message) End Try ……
|
1.1.3 从队列接收消息
清单4-14演示从本地设备上的myQueue队列接收消息。
清单 4-14 从队列接收消息
…… ' 与队列建立连接 Dim myQueue As New System.Messaging.MessageQueue("./myQueue")
' 设置消息体格式 Dim targetTypes() As Type targetTypes = New Type() {GetType(Order)} myQueue.Formatter = New System.Messaging.XmlMessageFormatter(targetTypes) Try ' 接收并格式化消息 Dim myMessage As System.Messaging.Message = myQueue.Receive() Dim myOrder As Order = CType(myMessage.Body, Order)
' 显示消息内容 MsgBox("Order ID: " & _ myOrder.orderID.ToString() & _ Chr(10) & "Sent: " & myOrder.orderTime.ToString()) Catch m As System.Messaging.MessageQueueException ' 处理消息队列抛出的例外 MsgBox(m.Message) Catch ex As InvalidOperationException ' 处理无效序列化格式 MsgBox(ex.Message) End Try …… |