刚刚毕业一年,比较浮躁,上次面试被问到消息队列,觉得非常的惭愧因为不知道,所以下定决心一定要学会使用它。以前只是听说过有这么个东西,要说是什么,在什么场景下使用却是无从知晓,因为自己也确实没有在项目中用过,毫无底气能够去和面试官谈论一番。好了现在就开始一步步学习吧!
首先我们要知道消息队列是什么? 我是被网络上的解释忽悠的一愣一愣的,来个个人通俗的解释吧,消息队列顾名思义它首先得是个队列,队列的操作呢一班主要的也就是入队和出队,也就是你有一个程序在产生消息内容后(也就是你想发送的内容,比如一个字符串,一本书等等),也就是入队(即生产者),另一个程序呢读取消息队列,读出你发送进入的消息内容,这就是出队(消费者);那么这样的情况一般我们会在什么情况下去使用消息队列呢?总结大神的一句话:当你不需要立即获得结果,但是并发量又不能无限大的时候,差不多就是你需要使用消息队列的时候.比如你写日志的时候,一个客户端有多个操作区写日志,又有很多个客户端去写,显然并发不能无穷大,于是你就需要把写日志的请求放入消息队列中,在消费者那边依次取出队列的消息写入到日志里。
一.MSMQ的安装
关于MSMQ的介绍我就不多说了,想知道的自己百度,http://www.oschina.net/translate/top-10-uses-for-message-queue
具体的安装过程就是 控制面板->卸载程序->打开或者关闭Windows功能,选择MSMQ,如下图,点击确定即可;
创建队列的方式如上,还有另外一种方式,通过代码编程来实现,在.NetFramework中国提供了MessageQueue类下的静态方法Crate(),来实现消息队列的创建,其定义如下
1 1// 2 3 2// 摘要: 4 5 3// 在指定的路径中创建非事务性“消息队列”队列。 6 7 4// 8 9 5// 参数: 10 11 6// path: 12 13 7// 要创建的队列的路径。 14 15 8// 16 17 9// 返回结果: 18 19 10// 表示新队列的 System.Messaging.MessageQueue。 20 21 11public static MessageQueue Create(string path); 22 23 12// 24 25 13// 摘要: 26 27 14// 在指定的路径中创建事务性或非事务性“消息队列”队列。 28 29 15// 30 31 16// 参数: 32 33 17// transactional: 34 35 18// 如果创建事务性队列,为 true;如果创建非事务性队列,则为 false。 36 37 19// 38 39 20// path: 40 41 21// 要创建的队列的路径。 42 43 22// 44 45 23// 返回结果: 46 47 24// 表示新队列的 System.Messaging.MessageQueue。 48 49 25public static MessageQueue Create(string path, bool transactional);
二.创建,删除和管理队列
在.Net平台下编写消息队列的程序,我们必须学习一个很重要的类MessageQueue,该类位于命名空间System.Messageing下,其中有几个常用的方法必须掌握:
---Create方法:创建使用指定路径的新消息队列
---Delete方法:删除现有的消息队列
---Existe方法:查看指定消息队列是否存在
---GetAllMessages()方法:得到队列中的所有消息
---Peek/BeginPeek方法:查看某个特定队列中的消息队列,但不从该队列中移出消息
---Receive/BeginReceive方法:检索指定消息队列中最前面的消息并将其从该队列中移除
---Send方法:发送消息到指定的消息队列
---Purge方法:清空指定队列的消息
三.发送和序列化消息
MSMQ消息队列中定义的消息由一个主体和若干属性组成,消息的主体可以又文本,二进制构成,根据需要还可以考虑被加密,在MSMQ中消息的大小不能够超过4M。
1.发送消息步骤: 连接队列->指定消息格式->提供要发送的数据(主体)->调用send()方法将消息发送出去;
2.序列化消息:消息序列化可以通过.Net框架附带的三个预定义格式化程序来完成,
XMLMessageFormatter,BinaryMessageFormatter,ActiveXMessageFormatter
3.消息发送实例
现在有这样一个需求,要求通过消息队列将一本图书信息发送到队列里,然后从消息队列里读取出来。图书的基本信息包括图书编号、图书名称、图书作者以及图书定价,这样的一个复杂的对象类型怎么来传输呢?详细如下:
传递对象
using System; using System.Collections.Generic; using System.Text; namespace MSMQ { public class Book { public int BookId { get; set; } public string BookName { get; set; } public string BookAuthor { get; set; } public double BookPrice { get; set; } } }
MSMQ操作
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Messaging; using System.Windows.Forms; namespace MSMQ { class MSMQOperation { /// <summary> /// 通过Create方法创建使用指定路径的新消息队列 /// </summary> /// <param name="queuePath"></param> public static void Createqueue(string queuePath) { try { if (!MessageQueue.Exists(queuePath)) { MessageQueue.Create(@".\private$\myQueue"); MessageBox.Show("创建队列成功!"); } else { MessageBox.Show(queuePath + "已经存在!"); } } catch (MessageQueueException e) { MessageBox.Show(e.Message); } } /// <summary> /// 连接消息队列并发送消息到队列 /// </summary> public static bool SendMessage(Book book) { bool flag = false; try { //连接到本地的队列 MessageQueue myQueue = new MessageQueue(".\\private$\\myQueue"); System.Messaging.Message myMessage = new System.Messaging.Message(); myMessage.Body = book; myMessage.Formatter = new XmlMessageFormatter(new Type[] { typeof(Book) }); //发送消息到队列中 myQueue.Send(myMessage); flag = true; } catch (ArgumentException e) { MessageBox.Show(e.Message); } return flag; } public static string ReceiveMessage() { MessageQueue myqueue = new MessageQueue(@".\private$\myQueue"); myqueue.Formatter = new XmlMessageFormatter(new Type[] { typeof(Book) }); try { System.Messaging.Message myMessage=myqueue.Receive(); Book book= myMessage.Body as Book; return string.Format("编号:{0},书名:{1},作者:{2},定价:{3}", book.BookId, book.BookName, book.BookAuthor, book.BookPrice); } catch (MessageQueueException e) { MessageBox.Show(e.Message); } catch (InvalidCastException e) { MessageBox.Show(e.Message); } return null; } } }
这里简单的使用就介绍到这里了,后期想学习petshop,学习下单处理策略据说不错