本文继续介绍MSMQ的相关知识点,通过一个示例程序来分析MSMQ在实际项目开发中的应用。
建议:如果你对MSMQ不够了解,在你阅读本文前请先阅读第一部分:《ASP.NET中进行消息处理(MSMQ)一》。
一、消息传递的优先级
在MSMQ中消息在队列里传输是分有优先级的,这里我就以实例的形式介绍下关于优先级的使用,优先级一共有七种,MessagePriority枚举里全部进行了封装。因这里只作程序演示就不一一列举出,仅用了Highest和Normal两种类型,关于消息队列上进行消息传输的七种优先级大家可以参考我下面提供的MessagePriority枚举源代码定义。
那么在发送消息的时候怎么指定消息的优先级呢?在Message对象里封装有一个属性Priority,接受一个枚举MessagePriority类型的值来设置消息传输的优先级。如下:
| 1System.Messaging.Message message = new System.Messaging.Message(); 2message.Priority = MessagePriority.Highest; //最高消息优先级 |
下面来看看一个在消息传输中使用优先级的示例程序,通过示例程序会学习得更明白。示例程序界面:

根据界面可知,提供了消息名字,消息优先级和消息内容三个输入项,前面曾经说过,这里为了方便演示就仅用了Highest和Normal两种类型,当点击发送消息的时候就通过是否选择优先级来设置消息的优先级,代码如下:
| 1private void btnSend_Click(object sender, EventArgs e) 2{ 3 //连接到本地的专用队列myQueue 4 MessageQueue myQueue = new MessageQueue(".\\private$\\myQueue"); 5 System.Messaging.Message message = new System.Messaging.Message(); 6 message.Label = tbName.Text; 7 message.Body = tbContext.Text; 8 9 if (cbPriority.Checked) 10 { 11 message.Priority = MessagePriority.Highest; 12 } 13 else 14 { 15 message.Priority = MessagePriority.Normal; 16 } 17 myQueue.Send(message); 18 MessageBox.Show("成功发送消息到队列"); 19} |
这里我们可以向队列里发送两条消息,以便后面测试读取方法,发送两条消息到队列,此时,从队列消息中可以看到:

"刷新队列"实质上就是把队列里的消息全部读取出来,具体的实现在《ASP.NET中进行消息处理(MSMQ)一》里已经作了详细的介绍,这里就不在多说,看看下面的代码:
| 1private void DisplayMessage() 2 { 3 //连接到本地队列 4 MessageQueue myQueue = new MessageQueue(".\\private$\\myQueue"); 5 myQueue.MessageReadPropertyFilter.Priority = true; 6 DataTable messageTable = new DataTable(); 7 messageTable.Columns.Add("名字"); 8 messageTable.Columns.Add("消息内容"); 9 messageTable.Columns.Add("优先级"); 10 XmlMessageFormatter formatter = new XmlMessageFormatter(new string[] { "System.String" }); 11 try 12 { 13 //从队列中接收消息 14 System.Messaging.Message[] messages = myQueue.GetAllMessages(); 15 for (int index = 0; index < messages.Length; index++) 16 { 17 messages[index].Formatter = formatter; 18 19 string label = messages[index].Label; 20 string body = messages[index].Body.ToString(); 21 string priority = messages[index].Priority.ToString(); 22 23 messageTable.Rows.Add(new string[] { label, body, priority }); 24 } 25 this.dgvMessage.DataSource = messageTable; 26 } 27 catch (MessageQueueException e1) 28 { 29 MessageBox.Show(e1.Message); 30 } 31 } 32 } |
这里封装了一方法,专门负责从队列里读取全部消息并绑定在DataGridView控件上,这里我们只需要在按扭Click事件里调用这方法就OK。
| 1private void btnRec_Click(object sender, EventArgs e) 2{ 3 DisplayMessage(); 4} |
这就完成了给消息设置优先级的消息传输的应用,最终的测试结果如下:

注:要完成以上应用还需注意一点,由于消息的优先级是枚举类型,在直接messages[index].Priority.ToString();这种方式来获取优先级转化到字符串的时候,他需要一个过滤器(Filter),否则会抛出一个InvalidCastExceptionle类型的异常,异常信息"接收消息时未检索到属性 Priority。请确保正确设置了 PropertyFilter。",要解决这问题只需要把消息对象的MessageReadPropertyFilter(过滤器) 的Priority设置为true就OK了。见上面代码里!^.^
MessagePriority枚举源代码定义详细如下:
| 1// 摘要: 2// 指定消息队列在消息传递到队列的过程中应用于该消息的优先级,以及指定何时将消息插入目标队列。 3public enum MessagePriority 4{ 5 // 摘要: 6 // 最低消息优先级。 7 Lowest = 0, 8 // 9 // 摘要: 10 // 位于 Low 和 Lowest 消息优先级之间。 11 VeryLow = 1, 12 // 13 // 摘要: 14 // 低消息优先级。 15 Low = 2, 16 // 17 // 摘要: 18 // 普通消息优先级。 19 Normal = 3, 20 // 21 // 摘要: 22 // 位于 System.Messaging.MessagePriority.High 和 System.Messaging.MessagePriority.Normal 23 // 消息优先级之间。 24 AboveNormal = 4, 25 // 26 // 摘要: 27 // 高消息优先级。 28 High = 5, 29 // 30 // 摘要: 31 // 位于 Highest 和 High 消息优先级之间。 32 VeryHigh = 6, 33 // 34 // 摘要: 35 // 最高消息优先级。 36 Highest = 7, 37} |