.Net下的MSMQ的同步异步调用

<script type="text/javascript"> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
<script type="text/javascript"> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>

一、MSMQ简介

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

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

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

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

二、消息队列的安装

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

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

三、消息队列类型

消息对列分为3类:
 
公共队列

MachineName/QueueName

能被别的机器所访问,如果你的多个项目中用到消息队列,那么你可以把队列定义为公共队列
 
专用队列

MachineName/Private$/QueueName

只针对于本机的程序才可以调用的队列,有些情况下为了安全起见定义为私有队列。

日志队列

MachineName/QueueName/Journal$

四、消息队列的创建

MessageQueueMq=newMessageQueue(“.//private$//Mymq”);

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

MessageQueueMq=newMessageQueue();

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

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

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

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

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

五、消息的发送

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

Mq.Send("Hello!");

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

六、消息的接收和阅读

(1)同步接收消息

 接收消息的代码很简单:

 Mq.Receive();
       Mq.Receive(TimeSpantimeout);//设定超时时间
 Mq.ReceiveById(ID);
       Mq.Peek();
 
通过Receive方法接收消息同时永久性地从队列中删除消息;

通过Peek方法从队列中取出消息而不从队列中移除该消息。

如果知道消息的标识符(ID),还可以通过ReceiveById方法和PeekById方法完成相应的操作。

(2)异步接受消息
  
利用委托机制:MessQueue.ReceiveCompleted+=newReceiveCompletedEventHandler(mq_ReceiveCompleted);
 
(3)消息阅读

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

 publicvoidmq_ReceiveCompleted(objectsender,System.Messaging.ReceiveCompletedEventArgse)
 {
  System.Messaging.Messagem=MessQueue.EndReceive(e.AsyncResult);
  m.Formatter=newSystem.Messaging.XmlMessageFormatter(newstring[]{"System.String,mscorlib"});
  Console.WriteLine("Message:"+(string)m.Body);
  MessQueue.BeginReceive();

 }

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

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


1usingSystem;
 2usingSystem.Messaging;
 3usingSystem.Threading;

 5
 6namespaceLoveStatusService
 7{
 8   /**<summary>
 9   ///SummarydescriptionforMSMQ.
 10   ///</summary>
 11   publicclassMSMQ
 12   {
 13       publicMSMQ()
 14       {
 15           //
 16           //TODO:Addconstructorlogichere
 17           //
 18       }
 19
 20       
 21       privateMessageQueue_messageQueue=null;
 22       //最大并发线程数
 23       privatestaticintMAX_WORKER_THREADS=Convert.ToInt32(System.Configuration.ConfigurationSettings.AppSettings["MAX_WORKER_THREADS"].ToString());
 24       //MSMQ路径
 25       privatestaticstringMSMQPath=System.Configuration.ConfigurationSettings.AppSettings["LoveStatusMQPath"];
 26       //等待句柄
 27       privateWaitHandle[]waitHandleArray=newWaitHandle[MAX_WORKER_THREADS];
 28       //任务类型
 29       //1.SendEmail2.SendMessage 3.SendEmailandMessage
 30       privatestringTaskType=System.Configuration.ConfigurationSettings.AppSettings["TaskType"];
 31       publicMessageQueueMessQueue
 32       {
 33           get
 34           {
 35           
 36               if(_messageQueue==null)
 37               {
 38                   if(MessageQueue.Exists(MSMQPath))
 39                   {
 40                       _messageQueue=newMessageQueue(MSMQPath);   
 41                   }
 42                   else
 43                   {
 44                       _messageQueue=MessageQueue.Create( MSMQPath);   
 45                   }   
 46               }
 47               
 48
 49               return_messageQueue;
 50           }
 51       }
 52       
 53
 54   PrivateMethod#regionPrivateMethod
 55
 56       privatevoidmq_ReceiveCompleted(objectsender,System.Messaging.ReceiveCompletedEventArgse)
 57       {
 58           MessageQueuemqq=(MessageQueue)sender;
 59           System.Messaging.Messagem=mqq.EndReceive(e.AsyncResult);
 60           //m.Formatter=newSystem.Messaging.XmlMessageFormatter(newstring[]{"System.String,mscorlib"});
 61           m.Formatter=newSystem.Messaging.XmlMessageFormatter(newType[]{typeof(UserObject)});


 62           //log.Info("ReceiveUserID:"+(string)m.Body);
 63           UserObjectobj=(UserObject)m.Body;
 64           longcurUserId=obj.curUserID;
 65           longoppUserId=obj.oppUserID;
 66           stringcurUserName=obj.curUserName;
 67           stringoppUserName=obj.oppUserName;
 68           stringcurEmail=obj.curEmail;
 69           stringoppEmail=obj.oppEmail;
 70           stringsubject=obj.subject;


 71           stringbody=obj.body;
 72           //AppLog.log.Info("curUserId:"+curUserId);
 73           //AppLog.log.Info("oppUserId:"+oppUserId);
 74           AppLog.log.Info("==type="+TaskType);
 75           switch(TaskType)
 76           {
 77               //Email
 78               case"1":
 79                   EmailForMQ.SendEmailForLoveStatus(curEmail,oppEmail,curUserName,oppUserName,subject);
 80                   AppLog.log.Info("==Sendto=="+oppEmail);
 81                   break;
 82               //Message
 83               case"2":
 84                   MessageForMQ.SendMessage(curUserId,oppUserId,subject,body);
 85                   AppLog.log.Info("==SendMsgto=="+oppUserId);
 86                   break;
 87               //EmailandMessage       
 88               case"3":
 89                   EmailForMQ.SendEmailForLoveStatus(curEmail,oppEmail,curUserName,oppUserName,subject);
 90                   AppLog.log.Info("==Sendto=="+oppEmail);
 91                   MessageForMQ.SendMessage(curUserId,oppUserId,subject,body);
 92                   AppLog.log.Info("==SendMsgto=="+oppUserId);
 93                   break;
 94               default:
 95                   break;
 96
 97           }
 98           mqq.BeginReceive();
 99
100       }
101
102   #endregion
103
104   PublicMethod#regionPublicMethod
105
106       //一个将对象发送到队列的方法,这里发送的是对象
107       publicvoidSendUserIDToMQ(objectarr)
108       {
109           MessQueue.Send(arr);


110           Console.WriteLine("Ok");
111           Console.Read();
112       }
113
114       //同步接受队列内容的方法
115       publicvoidReceiveFromMQ()
116       {
117           Messagems=newMessage();
118           
119           //ms=MessQueue.Peek();
120           try
121           {
122               ms=MessQueue.Receive(newTimeSpan(0,0,5));


123               if(ms!=null)
124               {
125                   ms.Formatter=newXmlMessageFormatter(newType[]{typeof(string)});
126                   AppLog.log.Info((string)ms.Body) ;
127               }
128           }
129           catch(Exceptionex)
130           {
131               


132           }
133           
134       
135       }
136
137       //开始监听工作线程
138       public voidstartListen()
139       {
140           AppLog.log.Info("--Thread--"+MAX_WORKER_THREADS);
141           MessQueue.ReceiveCompleted+=newReceiveCompletedEventHandler(mq_ReceiveCompleted);
142           
143           //异步方式,并发
144           
145           for(inti=0;i<MAX_WORKER_THREADS;i++)
146           {
147               //Beginasynchronousoperations.
148               waitHandleArray[i]=MessQueue.BeginReceive().AsyncWaitHandle;
149           }
150
151           AppLog.log.Info("------StartListen--------");
152
153           return;
154
155       }
156
157
158       //停止监听工作线程
159       publicvoidstopListen()
160       {
161
162           for(inti=0;i<waitHandleArray.Length;i++)
163           {
164
165               try
166               {
167                   waitHandleArray[i].Close();
168               }
169               catch
170               {
171                   AppLog.log.Info("---waitHandleArray[i].Close()Error!-----"); 共4页: 上一页 1 [2] [3] [4] 下一页 <script type="text/javascript"> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
<script type="text/javascript"> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值