.Net下的MSMQ(微软消息队列)的同步异步调用

一、MSMQ简介

 MSMQ(微软消息队列)是Windows操作系统中消息应用程序的基础,是用于创建分布式、松散连接的消息通讯应用程序的开发工具。消息队列

和电子邮件有着很多相似处,他们都包含多个属性,用于保存消息,消息类型中都指出发送者和接收者的地址;然而他们的用处却有着很大的

区别:消息队列的发送者和接收者是应用程序,而电子邮件的发送者和接收者通常是人。如同电子邮件一样,消息队列的发送和接收也不需要

发送者和接收者同时在场,可以存储在消息队列或是邮件服务器中。

 

二、消息队列的安装

 默认情况下安装操作系统是不安装消息队列的,你可以在控制面板中找到添加/删除程序,然后选择添加/删除Windows组件一项,然后选择应

用程序服务器,双击它进入详细资料中选择消息队列一项进行安装,如图:







三、消息队列类型

消息对列分为3类:
 
公共队列
 MachineName\QueueName
 能被别的机器所访问,如果你的多个项目中用到消息队列,那么你可以把队列定义为公共队列
 
专用队列
 MachineName\Private$\QueueName
 只针对于本机的程序才可以调用的队列,有些情况下为了安全起见定义为私有队列。
日志队列
 MachineName\QueueName\Journal$
 

四、消息队列的创建

MessageQueue Mq=new MessageQueue(“.\\private$\\Mymq”);

通过Path属性引用消息队列的代码也十分简单:

MessageQueue Mq=new MessageQueue();

Mq.Path=”.\\private$\\Mymq”;

使用 Create 方法可以在计算机上创建队列:

System.Messaging.MessageQueue.Create(@".\private$\Mymq");

这里注意由于在C#中要记住用反斜杠将“\”转义。

由于消息对列所放置的地方经常改变,所以建议消息队列路径不要写死,建议放在配置文件中。

五、消息的发送

消息的发送可以分为简单消息和复杂消息,简单消息类型就是常用的数据类型,例如整型、字符串等数据;复杂消息的数据类型通常对应于系

统中的复杂数据类型,例如结构,对象等等。

Mq.Send("Hello!");
在这里建议你可以事先定义一个对象类,然后发送这个对象类的实例对象,这样以后无论在增加什么发送信息,只需在对象类中增加
相应的属性即可。

六、消息的接收和阅读

(1)同步接收消息

  接收消息的代码很简单:

 Mq.Receive();
        Mq.Receive(TimeSpan timeout); //设定超时时间
 Mq.ReceiveById(ID);
        Mq.Peek();
 
 通过Receive方法接收消息同时永久性地从队列中删除消息;
 通过Peek方法从队列中取出消息而不从队列中移除该消息。
 如果知道消息的标识符(ID),还可以通过ReceiveById方法和PeekById方法完成相应的操作。

(2)异步接受消息
  
   利用委托机制:

 MessQueue.ReceiveCompleted +=new ReceiveCompletedEventHandler(mq_ReceiveCompleted);
 


(3)消息阅读

在应用程序能够阅读的消息和消息队列中的消息格式不同,应用程序发送出去的消息经过序列化以后才发送给了消息队列
而在接受端必须反序列化,利用下面的代码可以实现:

 public void mq_ReceiveCompleted(object sender, System.Messaging.ReceiveCompletedEventArgs e)
  {
   System.Messaging.Message m = MessQueue.EndReceive(e.AsyncResult);
   m.Formatter = new System.Messaging.XmlMessageFormatter(new string[]{"System.String,mscorlib"});
   Console.WriteLine("Message: " + (string)m.Body);
   MessQueue.BeginReceive() ;

  }

反序列化还有另一种写法:
 m.Formatter = new XmlMessageFormatter ( new Type [] { typeof (string) } );

 

七、由于消息队列的代码有些是固定不便的,所以把这些代码封装成一个类方便以后使用:

  1using System;
  2using System.Messaging;
  3using System.Threading;

  5
  6namespace LoveStatusService
  7{
  8    /// <summary>
  9    /// Summary description for Msmq.
 10    /// </summary>

 11    public class Msmq
 12    {
 13        public Msmq()
 14        {
 15            //
 16            // TODO: Add constructor logic here
 17            //
 18        }

 19
 20        
 21        private MessageQueue _messageQueue=null;
 22        //最大并发线程数 
 23        private static int MAX_WORKER_THREADS=Convert.ToInt32( System.Configuration.ConfigurationSettings.AppSettings["MAX_WORKER_THREADS"].ToString());
 24        //Msmq路径
 25        private static string MsmqPath=System.Configuration.ConfigurationSettings.AppSettings["LoveStatusMQPath"];
 26        //等待句柄
 27        private WaitHandle[] waitHandleArray = new WaitHandle[MAX_WORKER_THREADS];
 28        //任务类型
 29        //1. Send Email 2. Send Message  3. Send Email and Message
 30        private string TaskType=System.Configuration.ConfigurationSettings.AppSettings["TaskType"];
 31        public MessageQueue MessQueue
 32        {
 33            get
 34            {
 35            
 36                if (_messageQueue==null)
 37                {
 38                    if(MessageQueue.Exists(MsmqPath))
 39                    {
 40                        _messageQueue = new MessageQueue(MsmqPath);    
 41                    }

 42                    else
 43                    {
 44                        _messageQueue = MessageQueue.Create(MsmqPath);    
 45                    }
    
 46                }

 47                
 48
 49                return _messageQueue;
 50            }

 51        }

 52        
 53
 54    Private Method
103
104    Public Method
190    
191    
192
193    
194    }

195}

196

UserObject的代码

  1using System;
  2
  3namespace Goody9807
  4{
  5    /// <summary>
  6    /// 用与在MQ上传输数据的对象
  7    /// </summary>

  8    public class UserObject
  9    {
 10        public UserObject()
 11        {
 12            //
 13            // TODO: Add constructor logic here
 14            //
 15        }

 16
 17        private long _curUserID;
 18        public long curUserID
 19        {
 20            get
 21            {
 22                return _curUserID;
 23            }

 24            set
 25            {
 26                _curUserID=value;
 27            }

 28        }

 29
 30        private  string _curUserName="";
 31        public string curUserName
 32        {
 33            get
 34            {
 35                return _curUserName;
 36            }

 37            set
 38            {
 39                _curUserName=value;
 40            }

 41        }

 42
 43        private string _curEmail="";
 44        public string curEmail
 45        {
 46            get
 47            {
 48                return _curEmail;
 49            }

 50            set
 51            {
 52                _curEmail=value;
 53            }

 54        }

 55
 56
 57        private long _oppUserID;
 58        public long oppUserID
 59        {
 60            get
 61            {
 62                return _oppUserID;
 63            }

 64            set
 65            {
 66                _oppUserID=value;
 67            }

 68        }

 69
 70        private  string _oppUserName="";
 71        public string oppUserName
 72        {
 73            get
 74            {
 75                return _oppUserName;
 76            }

 77            set
 78            {
 79                _oppUserName=value;
 80            }

 81        }

 82
 83        private string _oppEmail="";
 84        public string oppEmail
 85        {
 86            get
 87            {
 88                return _oppEmail;
 89            }

 90            set
 91            {
 92                _oppEmail=value;
 93            }

 94        }

 95
 96        private string _subject ="";
 97        public string subject
 98        {
 99            get
100            {
101                return _subject;
102            }

103            set
104            {
105                _subject=value;
106            }

107        }

108
109        private string _body="";
110        public string body
111        {
112            get
113            {
114                return _body;
115            }

116            set
117            {
118                _body=value;
119            }

120        }

121    }

122}

123

另一个同事写的封装类



posted @ 2007-05-18 10:00  PointNet  阅读(10640)  评论(17编辑  收藏  举报