.Net下的MSMQ的同步异步调用
2009-12-15 22:44
127 查看
一、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) } );
七、由于消息队列的代码有些是固定不便的,所以把这些代码封装成一个类方便以后使用:
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#region Private Method 55 56 private void mq_ReceiveCompleted(object sender, System.Messaging.ReceiveCompletedEventArgs e) 57 { 58 MessageQueue mqq = (MessageQueue)sender; 59 System.Messaging.Message m = mqq.EndReceive(e.AsyncResult); 60 //m.Formatter = new System.Messaging.XmlMessageFormatter(new string[]{"System.String,mscorlib"}); 61 m.Formatter =new System.Messaging.XmlMessageFormatter(new Type[] {typeof(UserObject)}) ; 62 //log.Info("Receive UserID: " + (string)m.Body) ; 63 UserObject obj=(UserObject)m.Body ; 64 long curUserId=obj.curUserID ; 65 long oppUserId=obj.oppUserID; 66 string curUserName=obj.curUserName; 67 string oppUserName=obj.oppUserName; 68 string curEmail=obj.curEmail ; 69 string oppEmail=obj.oppEmail; 70 string subject =obj.subject ; 71 string body=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("==Send to=="+oppEmail) ; 81 break; 82 //Message 83 case "2": 84 MessageForMQ.SendMessage(curUserId,oppUserId,subject,body) ; 85 AppLog.log.Info("==Send Msg to=="+oppUserId) ; 86 break; 87 //Email and Message 88 case "3": 89 EmailForMQ.SendEmailForLoveStatus(curEmail,oppEmail,curUserName,oppUserName,subject) ; 90 AppLog.log.Info("==Send to=="+oppEmail) ; 91 MessageForMQ.SendMessage(curUserId,oppUserId,subject,body) ; 92 AppLog.log.Info("==Send Msg to=="+oppUserId) ; 93 break; 94 default: 95 break; 96 97 } 98 mqq.BeginReceive() ; 99 100 } 101 102 #endregion 103 104 Public Method#region Public Method 105 106 //一个将对象发送到队列的方法,这里发送的是对象 107 public void SendUserIDToMQ(object arr) 108 { 109 MessQueue.Send(arr) ; 110 Console.WriteLine("Ok") ; 111 Console.Read() ; 112 } 113 114 //同步接受队列内容的方法 115 public void ReceiveFromMQ() 116 { 117 Message ms=new Message() ; 118 119 //ms=MessQueue.Peek(); 120 try 121 { 122 ms=MessQueue.Receive(new TimeSpan(0,0,5)); 123 if(ms!=null) 124 { 125 ms.Formatter = new XmlMessageFormatter ( new Type [] { typeof (string) } ); 126 AppLog.log.Info((string)ms.Body) ; 127 } 128 } 129 catch(Exception ex) 130 { 131 132 } 133 134 135 } 136 137 //开始监听工作线程 138 public void startListen() 139 { 140 AppLog.log.Info("--Thread--"+MAX_WORKER_THREADS) ; 141 MessQueue.ReceiveCompleted +=new ReceiveCompletedEventHandler(mq_ReceiveCompleted); 142 143 //异步方式,并发 144 145 for(int i=0; i<MAX_WORKER_THREADS; i++) 146 { 147 // Begin asynchronous operations. 148 waitHandleArray[i] = MessQueue.BeginReceive().AsyncWaitHandle; 149 } 150 151 AppLog.log.Info("------Start Listen--------") ; 152 153 return; 154 155 } 156 157 158 //停止监听工作线程 159 public void stopListen() 160 { 161 162 for(int i=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!-----") ; 172 } 173 174 } 175 176 try 177 { 178 // Specify to wait for all operations to return. 179 WaitHandle.WaitAll(waitHandleArray,1000,false); 180 } 181 catch 182 { 183 AppLog.log.Info("---WaitHandle.WaitAll Error!-----") ; 184 } 185 AppLog.log.Info("------Stop Listen--------") ; 186 187 } 188 189 #endregion 190 191 192 193 194 } 195} 196 serObject的代码
|
相关文章推荐
- .Net下的MSMQ(微软消息队列)的同步异步调用
- .Net下的MSMQ的同步异步调用
- .Net下的MSMQ(微软消息队列)的同步异步调用 (转载)
- .Net下的MSMQ(微软消息队列)的同步异步调用
- .Net下的MSMQ的同步异步调用
- 疯狂.NET 通用权限设计 C/S后台管理,B/S前台调用源码样例程序源码下载之 --- 数据集权限
- .NET动态调用Web Service服务
- sqlserver中调用.net中的dll
- [翻译]在SQL Server中使用CLR调用.NET方法 【转】
- flex 调用WebService1(基于.net)
- .Net——动态调用方法
- 在.net中调用datawindow操作数据库
- 解决调用.net写的webservice 参数变为 null
- .NET 下的 jQuery UI 开源控件 - JQueryElement, 简化 js 脚本编写, 提供更方便的 ajax 调用[1]
- 使用WCF进行跨平台开发之一(WCF的实现、控制台托管与.net平台的调用)
- Java与.NET的WebServices相互调用
- [转贴]在.net 中调用VBA
- ASP、VB调用.NET编写的DLL
- JAVA如何调用.NET开发的WebService
- .Net下采用GET/POST/SOAP方式动态调用WebService的简易灵活方法(C#)