直到今天才知道,在我们每天都在用的Window系统里还有这么好用的一个编程组件:消息队列.它能够解决在大数据量交换的情况下的性能问题,特别是BS系统的数据库性能.而且它的异步处理方式能给程序员最大的便利与最好的用户体验.

1.首先在需要进行消息队列的服务器上安装MSMQ,我的系统是win2003+iis6,所以这个安装选项在添加删除程序->windows组件->应用程序服务器内.默认是不安装的,需要手动选择.

2.建立消息队列的存放路径.这可以在windows的计算机管理内添加,也可以在程序中添加.我是在程序中添加.

3.在.net中要引用System.Messaging;

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Messaging;
  4. namespace MSMQ
  5. {
  6. class Program
  7. {
  8. private const string path = @".\private$\ljz";
  9. private static MessageQueue queue = MessageQueue.Exists(path) ? new MessageQueue(path) : MessageQueue.Create(path, true);
  10. //private static List<string> list = new List<string>();
  11. public enum Level
  12. {
  13. Low,
  14. Normal,
  15. High
  16. }
  17. static void Main(string[] args)
  18. {
  19. Send("第一次!", Level.Low);
  20. Send("第二次!", Level.Normal);
  21. Send("第三次!", Level.High);
  22. Console.WriteLine(Receive());
  23. Console.WriteLine(Receive());
  24. Console.WriteLine(Receive());
  25. Send("异步第一次!", Level.Normal);
  26. Send("异步第二次!", Level.High);
  27. Send("异步第三次!", Level.Low);
  28. ReceiveByAsyn();
  29. //foreach (string str in list)
  30. //{
  31. //    Console.WriteLine(str);
  32. //}
  33. Console.ReadKey();
  34. }
  35. public static void Send(string content, Level level)
  36. {
  37. System.Messaging.Message message = new System.Messaging.Message();
  38. message.Formatter = new System.Messaging.BinaryMessageFormatter();
  39. message.Body = content;
  40. switch (level)
  41. {
  42. case Level.Low:
  43. message.Priority = MessagePriority.Low;
  44. break;
  45. case Level.High:
  46. message.Priority = MessagePriority.High;
  47. break;
  48. default:
  49. message.Priority = MessagePriority.Normal;
  50. break;
  51. }
  52. //MessageQueueTransaction tran = new MessageQueueTransaction();
  53. //try
  54. //{
  55. //    tran.Begin();
  56. //    queue.Send(message);
  57. //    tran.Commit();
  58. //}
  59. //catch
  60. //{
  61. //    tran.Abort();
  62. //}
  63. queue.Send(message, MessageQueueTransactionType.Automatic);
  64. }
  65. public static string Receive()
  66. {
  67. System.Messaging.Message message = queue.Receive();
  68. message.Formatter = new System.Messaging.BinaryMessageFormatter();
  69. return message.Body.ToString();
  70. }
  71. public static void ReceiveByAsyn()
  72. {
  73. queue.ReceiveCompleted += new ReceiveCompletedEventHandler(queue_ReceiveCompleted);
  74. queue.BeginReceive();
  75. }
  76. private static void queue_ReceiveCompleted(object sender, ReceiveCompletedEventArgs e)
  77. {
  78. MessageQueue queueTmp = sender as MessageQueue;
  79. System.Messaging.Message mess = queueTmp.EndReceive(e.AsyncResult);
  80. mess.Formatter = new System.Messaging.BinaryMessageFormatter();
  81. Console.WriteLine(mess.Body.ToString());
  82. //list.Add(mess.Body.ToString());
  83. queueTmp.BeginReceive();
  84. }
  85. }
  86. }

下面对以上代码作几点解释:

1.上面的代码没有加异常处理,其实像这类代码是一定要加异常处理的!

2.路径.消息队列有好几种,有的可以被别人访问,如公共队列,有的则只能自己访问,如:专用队列.具体的分类,请参看下面列出的参考文章.但不是每种都可以使用.象我这种工作组模式的电脑,只能使用专用队列,即只能自己访问自己.它们的路径写法是有区别的:

  1. Public:  [MachineName]\[QueueName]
  2. Private:  [MachineName]\Private$\[QueueName]

3.使用消息队列有两个重要的类:System.Messaging.Message与System.Messaging.MessageQueue.我之所以列出全名,是因为在.net中有同名类,不要弄混了.下面的MessageQueue与Message特指上面两个类.

MessageQueue是消息队列对象,里面有两个重要的方法:Send与Receive.顾名思义,Send是向消息队列发送消息,Receive是从消息队列接收消息.

Message是消息对象.它有两个重要的属性Formatter是其内容序列化格式属性,Body是其存放内容的主体.在上面的例子中我放的是字符串,其实它还可以放对象,前提是对象必须可以被序列化.

根据以上说的内容,己经可以写出一个消息队列的Demo了,但是还不够实用,下面要说的是其一些实用的属性.

1.优先级.不可否认,在实际应用中消息是有优先级的,有的消息重要需要优先被处理有的消息则一般.如何体现呢?Message对象有Priority属性,它有8个等级,我在上面的例子中只用了其中三个.通过设置优先级,可以实现让重要的消息优先被处理.

2.事务.有时候,在传输数据的过程中,需要保证数据的一致性,在数据库中常常用到事务,其实这里也有事务,在上面的例子中56-66行代码是事务处理,但是写的比较累赘,其实可以采用67行的写法,让系统自己去维护.

3.异步处理.MessageQueue对象的Receive方法有个缺点,当队列中没有数据时线程会锁死,直到有新的数据进入.这其实是不好的.一种更好的处理方式是新开辟一个线程去处理,这样就不会影响现有的线程了.在.net中写法为例子的80与81行,让消息对象加载一个委托,然后把处理代码放在委托内.

代码的第11行,32-35行,90行是我有意注掉的,其实我想的是当异步处理消息时,所做的应该只是把数据取出来就可以了,不应该还在里面进行处理.而是在别的地方再对数据进行处理.我声明了个局部变量list,按理说第90行数据取出来后应该能加入这个list,然而事实是取出的数据有时能加进去,有时却不行.我想这应该是多线程的问题..net默认禁止线程间互相内部调用.list是主线程的变量,打开异步后在子线程对其赋值,是不被允许的.但是我想不通的是为什么有时候却也能赋值成功.也许是我理解有误.如果哪位牛人看到了我的困惑,希望能对我指点一二.现在我对多线程还不甚了解.(汗一个~~~)

其实,个人认为,消息队列的应用范围还是比较有限的,首先,他只能是window系统,在.net下调用,然后,它对网络带宽要求比较高.所以在局域网内应用还是比较好的,在interent上的应用,其实有更好的解决方案:.net remoting与web services

Demo下载:

http://ljzforever.qupan.com/?folder=951925

参考的文章:

ASP.NET中进行消息处理(MSMQ)一

http://dev.yesky.com/178/8196178.shtml

ASP.NET中进行消息处理(MSMQ)二

http://dev.yesky.com/229/8196229.shtml

.net+msmq快速访问数据库

http://developer.ccidnet.com/art/322/20030214/37984_1.html

消息队列(Message Queue)简介及其使用

http://www.cnblogs.com/rickie/archive/2004/11/16/64345.html

msmq两个网域之间消息传输与接收测试总结

http://www.cnblogs.com/billqi/archive/2005/12/29/307371.html

MSMQ在ASP.NET中的应用问题?谢谢!

http://topic.csdn.net/t/20020829/11/979610.html

. Net环境下消息队列(MSMQ)对象的应用

http://www.cnblogs.com/rickie/archive/2004/11/17/64712.aspx

.net的MSMQ异步调用

http://www.wangchao.net.cn/bbsdetail_37204.html

使用MSMQ

http://myxq.cnblogs.com/archive/2005/03/15/119150.aspx

 

PetShop 4.0学习笔记:消息队列MSMQ的更多相关文章

  1. linux 进程学习笔记-消息队列messagequeue

    可以想象,如果两个进程都可以访问同一个队列:其中一个进程(sender)向其中写入结构化数据,另外一个进程(receiver)再从其中把结构化的数据读取出来.那么这两个进程就是在利用这个队列进行通信了 ...

  2. WCF分布式开发步步为赢(13):WCF服务离线操作与消息队列MSMQ

    之前曾经写过一个关于MSMQ消息队列的文章:WCF分布式开发必备知识(1):MSMQ消息队列 ,当时的目的也是用它来作为学习WCF 消息队列MSMQ编程的基础文章.在那篇文章里,我们详细介绍了MSMQ ...

  3. DirectX 总结和DirectX 9.0 学习笔记

    转自:http://www.cnblogs.com/graphics/archive/2009/11/25/1583682.html DirectX 总结 DDS DirectXDraw Surfac ...

  4. Storm学习笔记 - 消息容错机制

    Storm学习笔记 - 消息容错机制 文章来自「随笔」 http://jsynk.cn/blog/articles/153.html 1. Storm消息容错机制概念 一个提供了可靠的处理机制的spo ...

  5. C#使用消息队列(MSMQ)

    最近项目用到消息队列,找资料学习了下.把学习的结果 分享出来 首先说一下,消息队列 (MSMQ Microsoft Message Queuing)是MS提供的服务,也就是Windows操作系统的功能 ...

  6. 一起学ASP.NET Core 2.0学习笔记(二): ef core2.0 及mysql provider 、Fluent API相关配置及迁移

    不得不说微软的技术迭代还是很快的,上了微软的船就得跟着她走下去,前文一起学ASP.NET Core 2.0学习笔记(一): CentOS下 .net core2 sdk nginx.superviso ...

  7. vue2.0学习笔记之路由(二)路由嵌套+动画

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. vue2.0学习笔记之路由(二)路由嵌套

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. hdcms v5.7.0学习笔记

    hdcms v5.7.0学习笔记 https://note.youdao.com/ynoteshare1/index.html?id=c404d63ac910eb15a440452f73d6a6db& ...

随机推荐

  1. android Failure [INSTALL_FAILED_OLDER_SDK] 安装apk失败

    安装文件与运行环境的skd不匹配 打开源码目录下的AndroidManifest.xml文件,然后注释掉或者删除掉这行: <uses-sdk android:minSdkVersion=&quo ...

  2. 【Uva11212】 Editing a Book(IDA*)

    [题意] 有n个数字的全排列,每次可以剪切一段粘贴到某个位置.问最后变成升序最少多少步. 如"{2,4,1,5,3,6}要2步 {3,4,5,1,2}只要一步 [分析] 迭代深搜真的AC了也 ...

  3. bzoj2738

    感人肺腑pascal过不去系列,跪求开O2先不说这个了,学完cdq分治之后又顺手学了一下整体二分感觉这两个东西很多相似的地方,干脆都叫cdq分治好了二分解决k小就是设当前二分的答案为m,把x<= ...

  4. Win系统下制作U盘CLOVER引导+安装原版Mavericks10.9

    啃苹果有一段时间了,之前一直用白苹果,但是白苹果配置有所限制,对于我搞音频的人来讲,显得有点拖沓.所以研究了将近2年的黑苹果,最近心血来潮给大家一个比较傻瓜式的教程,首先强调一点,黑苹果是需要折腾的, ...

  5. [liu yanling]测试用例作用

    ⒈指导测试的实施 测试用例主要适用于集成测试.系统测试和回归测试.在实施测试时测试用例作为测试的标准,测试人员一定要按照测试用例严格按用例项目和测试步骤逐一实施测试.并对测试情况记录在测试用例管理软件 ...

  6. Centos 6.5升级安装Git

    安装需求 # yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel# yum install gcc pe ...

  7. [POJ1852]Ants

    Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 12431   Accepted: 5462 Description An a ...

  8. FCLK PCLK HCLK

    一.对clock的基本认识 1 s3c2410的clock & power management模块包含三个部分:clock control.usb control.power control ...

  9. (Step by Step)How to setup IP Phone Server(VoIP Server) for free.

    You must have heard about IP Phone and SIP (Software IP Phone).Nowadays standard PSTN phone are bein ...

  10. Sublime Text 2 使用心得

    一. 前言 作为一个前端,有一款好的开发利器是必不可少的,editplus.notepad++都是不错的工具,体积轻巧,启动迅速(dw太浮肿了).最近,又有一款新的编辑器诞生,席卷前端界,惹得无数喜爱 ...