最近小小地研究了一下MSMQ,如果把MSMQ用的灵活自如,炉火纯青那要花大功夫了,而且不能简单的用.net提供的MessageQueue类了, 这个类提供的功能太少。下面的包装类只提供了插入新数据到MSMQ和从MSMQ取数据,还有一个小特色,可以限制Queue里数据数目,如果达到指定数量, 就sleep一段时间。
首先,加入引用System.Messaging.dll, 以及Interop所使用的com:Microsoft Message Queue 3.0 Object Libray.
代码如下:
首先,加入引用System.Messaging.dll, 以及Interop所使用的com:Microsoft Message Queue 3.0 Object Libray.
代码如下:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Messaging;
- using System.Runtime.InteropServices;
- namespace Common
- {
- public class MSMQ<T> : IDisposable
- {
- MessageQueue queue = null;
- int upperLimit = 0;
- public MSMQ(string qName)
- : this(qName, 0)
- {
- }
- public MSMQ(string qName, int limit)
- {
- if (!string.IsNullOrEmpty(qName) && !MessageQueue.Exists(qName))
- {
- MessageQueue.Create(qName, true);
- }
- queue = new MessageQueue(qName);
- upperLimit = limit;
- }
- public T Pop()
- {
- T element = default(T);
- try
- {
- // 30秒内获取Message,超过30秒会引发超时异常
- using (Message m = queue.Receive(new TimeSpan(0, 0, 30)))
- {
- m.Formatter = new XmlMessageFormatter(new Type[] { typeof(T) });
- element = (T)m.Body;
- }
- }
- catch (MessageQueueException exp)
- {
- if (CurrentCount != 0)
- Console.WriteLine(exp.Message);
- }
- return element;
- }
- internal void Push(T[] elements)
- {
- if (elements != null)
- {
- foreach (T element in elements)
- {
- Push(element);
- }
- }
- }
- public void Push(T element)
- {
- using (MessageQueueTransaction ms = new MessageQueueTransaction())
- {
- ms.Begin();
- using (System.Messaging.Message message = new System.Messaging.Message())
- {
- message.Body = element;
- message.Formatter = new System.Messaging.XmlMessageFormatter(new Type[] { typeof(T) });
- // Put message into queue
- queue.Send(message, ms);
- }
- ms.Commit();
- }
- //若达到设定的上限,sleep一分钟.
- while (upperLimit != 0 && (CurrentCount >= upperLimit))
- {
- System.Threading.Thread.Sleep(60000);
- }
- }
- private int CurrentCount
- {
- get
- {
- MSMQ.MSMQManagement msmq = new MSMQ.MSMQManagement();
- object server = null;
- object path = queue.Path;
- object format = null;
- msmq.Init(ref server, ref path, ref format);
- int count = msmq.MessageCount;
- Marshal.ReleaseComObject(msmq);
- return count;
- }
- }
- #region IDisposable Members
- public void Dispose()
- {
- if (queue != null)
- queue.Dispose();
- if (logger != null)
- logger.Dispose();
- }
- #endregion
- }
- }