简介

MSMQ(微软消息队列)是Windows操作系统中消息应用程序的基础,是用于创建分布式、松散连接的消息通讯应用程序的开发工具。消息队列和电子邮件有着很多相似处,他们都包含多个属性,用于保存消息,消息类型中都指出发送者和接收者的地址;然而他们的用处却有着很大的区别:消息队列的发送者和接收者是应用程序,而电子邮件的发送者和接收者通常是人。

如同电子邮件一样,消息队列的发送和接收也不需要发送者和接收者同时在场,可以存储在消息队列或是邮件服务器中。因此,我们可以用下图来描述MSMQ应用程序的体系结构:

从上图可以看出,开发MSMQ应用程序并不是十分困难的事情。不过要使用MSMQ开发你的消息处理程序,必须在开发系统和使用程序的主机上安装消息队列。消息队列的安装属于Windows组件的安装,和一般的组件安装方法类似。安装好消息队列后,就可以开发你自己的消息处理程序了。不过有一点需要注意,如果你的计算机处于工作组中,而不是某个域中,可能你的公用队列不能使用,不过这并不影响你的程序开发。

消息处理程序不外乎消息的发送和接收,然而要收发消息,还必须引用一个队列,通常我们引用公用队列和专用队列,这两个队列都存放用户生成的消息。引用队列后,就可以发送、接收和阅读消息了。消息接收服务位于System.Messaging中,如果你找不到这一命名空间,你必须手动添加。点击[项目]中的[添加引用],按下浏览按钮,找到System.Messaging.dll文件,添加进来即可。

引用队列

引用队列有三种方法,通过路径、格式名和标签引用队列,这里我只介绍最简单和最常用的方法:通过路径应用队列。队列路径的形式为 machinename/queuename。指向队列的路径总是唯一的。下表列出用于每种类型的队列的路径信息:

队列类型

路径中使用的语法

公共队列

MachineName/QueueName

专用队列

MachineName/Private$/QueueName

日志队列

MachineName/QueueName/Journal$

如果是发送到本机上,还可以使用”.”代表本机名称。具体的引用方法通过Path属性来进行,也可以在初始化消息队列时进行。

如果在初始化时引用消息队列,那么消息队列必须存在于系统中,否则会产生中断。往系统中添加队列十分的简单,打开[控制面板]中的[计算机管理],展开[服务和应用程序],找到并展开[消息队列](如果找不到,说明你还没有安装消息队列),右击希望添加的消息队列的类别,选择新建队列即可。当然,在程序中也可以实现消息队列的创建,下文会有相应的说明。在初始化时引用消息队列的代码很简单,如下所示:

MessageQueue Mq=new MessageQueue(“.//private$//jiang”);

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

MessageQueue Mq=new MessageQueue();

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

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

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

发送消息

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

简单消息的发送示例如下:

Mq.Send(1000); //发送整型数据

Mq.Send(“This is a test message!”); //发送字符串

复杂消息的发送和简单消息的发送大同小异,只是发送时,通常不是直接给出发送的消息内容,而是代表发送消息内容的变量。下面的代码分别通过消息变量和复杂数据类型变量发送一条复杂消息。

//下面的代码中发送的消息由消息变量表示

Message Msg;

Msg=new Message(“A Complex Message!”);

Msg.Label=”This is the label”;

Msg.Priority=MessagePriority.High;

Mq.Send(Msg);

//下面的代码中发送的消息由复杂数据类型变量表示,Customer为自定义的一个类

          Customer customer = new Customer();

customer.LastName = "Copernicus";

customer.FirstName = "Nicolaus";

Mq.Send(customer);

接收消息

       接收消息相比发送消息要复杂一点。接收消息由两种方式:通过Receive方法接收消息同时永久性地从队列中删除消息;通过Peek方法从队列中取出消息而不从队列中移除该消息。如果知道消息的标识符(ID),还可以通过ReceiveById方法和PeekById方法完成相应的操作。

接收消息的代码很简单:

Mq.Receive(); //或Mq.ReceiveById(ID);

Mq.Peek();  // 或Mq.PeekById(ID);

阅读消息

接收到的消息只有能够读出来才是有用的消息,因此接收到消息以后还必须能读出消息,而读出消息算是最复杂的一部操作了。在应用程序能够阅读的消息和消息队列中的消息格式不同,因而应用程序发送出去的消息经过序列化以后才发送给了消息队列,这一过程由系统自动完成了,程序开发人员不必为此编写代码,然而在接收到消息后就面临着消息序列化的问题。

消息的序列化可以通过Visual Studio 和 .NET Framework 附带的三个预定义的格式化程序来完成:XMLMessageFormatter对象( MessageQueue组件的默认格式化程序设置)、BinaryMessageFormatter对象、ActiveXMessageFormatter对象。由于后两者格式化后的消息通常不能为人阅读,所以我们经常用到的是XMLMessageFormatter对象。

使用XMLMessageFormatter对象格式化消息的代码如下所示:

          string[] types = { "System.String" };

((XmlMessageFormatter)mq.Formatter).TargetTypeNames = types;

              Message m=mq.Receive(new TimeSpan(0,0,3));
       将接收到的消息传送给消息变量以后,通过消息变量m的Body

属性就可以读出消息了:

       MessageBox.Show((string)m.Body);

关闭消息队列

       消息队列的关闭很简单,和其他对象一样,通过Close

函数就可以实现了:

       Mq.Close();

到此为止,MSMQ应用程序的基础知识就介绍完全了,但是开发出一个功能强大的MSMQ应用程序显然不是这么简单,要了解更详细的资料可以参考MSDN和Windows操作系统中关于消息队列的帮助内容。

出处:http://blog.csdn.net/lotusswan/article/details/19939

使用C#和MSMQ开发消息处理程序的更多相关文章

  1. AspNetWebApi管线中如果定义两种类型的消息处理程序(全局/路由)

    AspNetWebApi管线中如果定义两种类型的消息处理程序(全局/路由) 在AspNetWebApi管线中存在两种类型的消息处理程序(Message Handler) 1.全局消息处理程序,所有的请 ...

  2. EJB_开发消息驱动bean

    开发消息驱动bean Java消息服务(Java MessageService) Java 消息服务(Java Message Service,简称 JMS)是用于访问企业消息系统的开发商中立的API ...

  3. Web API中的消息处理程序(Message Handler)

    一.消息处理程序的概念 信息处理程序(Message Handler)接收HTTP请求并返回一个HTTP响应的类.Message Handler继承 HttpMessageHandler 类. 通常, ...

  4. Web API 源码剖析之默认消息处理程序链之路由分发器(HttpRoutingDispatcher)

    Web API 源码剖析之默认消息处理程序链-->路由分发器(HttpRoutingDispatcher) 我们在上一节讲述了默认的DefaultServer(是一个类型为HttpServer的 ...

  5. 通过内存盘提高MSMQ的消息吞吐能力

    转载:http://www.ikende.com/blog/00f2634be4704b79a3e22439edeb1343 由于MSMQ的消息交互都需要对磁盘进行读写操作,所以提高MSMQ的消息吞吐 ...

  6. Web API 源码剖析之默认消息处理程序链--》路由分发器(HttpRoutingDispatcher)

    我们在上一节讲述了默认的DefaultServer(是一个类型为HttpServer的只读属性,详情请参考 Web API 源码剖析之全局配置).本节将讲述DefaultHandler(是一个Http ...

  7. EJB3.0 EJB开发消息驱动bean

    (7)EJB3.0 EJB开发消息驱动bean JMS 一: Java消息服务(Java Message Service) 二:jms中的消息 消息传递系统的中心就是消息.一条 Message 由三个 ...

  8. ASP.NET MVC5+EF6+EasyUI 后台管理系统(73)-微信公众平台开发-消息管理

    系列目录 前言 回顾上一节,我们熟悉的了解了消息的请求和响应,这一节我们来建立数据库的表,表的设计蛮复杂 你也可以按自己所分析的情形结构来建表 必须非常熟悉表的结果才能运用这张表,这表表的情形涵盖比较 ...

  9. .net微信公众号开发——消息与事件

    作者:王先荣    本文介绍如何处理微信公众号开发中的消息与事件,包括:(1)消息(事件)概况:(2)验证消息的真实性:(3)解析消息:(4)被动回复消息:(5)发送其他消息.    开源项目地址:h ...

随机推荐

  1. Confluence 6 连接到一个 LDAP 目录

    https://www.cwiki.us/display/CONFLUENCEWIKI/Connecting+to+an+LDAP+Directory

  2. 牛客练习赛23-A/B/C/D/F

    https://www.nowcoder.com/acm/contest/156#question 链接:https://www.nowcoder.com/acm/contest/156/A来源:牛客 ...

  3. javaweb web.xml版本

    web.xml版本的xsd分为如下几个版本 web-app_2_2.xsd web-app_2_3.xsd web-app_2_4.xsd web-app_2_5.xsd .... web-app_3 ...

  4. bzoj1215

    题解: 暴力枚举每一种方案,然后hash判重 代码: #include<bits/stdc++.h> #define eps 1e-7 using namespace std; ],r[] ...

  5. Delphi XE Starter Essentials 中文目录

    Table of Contents1. Delphi XE Starter IDE 1Delphi and C++Builder ................................... ...

  6. 设置MyEclipse字体大小

    设置MyEclipse字体大小

  7. C++ primer 第四版 练习3.13,3.14

    读一组整数到 vector 对象,计算并输出每对相邻元素的 和.如果读入元素个数为奇数,则提示用户后一个元素 没有求和,并输出其值. vector<int> ivec; int ival; ...

  8. java正则获取括号内的数据与排除括号内的数据

    1.正则获取括号内的数据 /** * 获取指定字符串中括号内的内容,返回字符串数组 * @param content * @return */ public String[] getBracketCo ...

  9. anu - proptypes

    //为了兼容yo var check = function () { return check; }; check.isRequired = check; export var PropTypes = ...

  10. Android中Parcel的分析以及使用

    简单点来说:Parcel就是一个存放读取数据的容器, Android系统中的binder进程间通信(IPC)就使用了Parcel类来进行客户端与服务端数据的交互,而且AIDL的数据也是通过Parcel ...