使用C#和MSMQ开发消息处理程序
简介
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开发消息处理程序的更多相关文章
- AspNetWebApi管线中如果定义两种类型的消息处理程序(全局/路由)
AspNetWebApi管线中如果定义两种类型的消息处理程序(全局/路由) 在AspNetWebApi管线中存在两种类型的消息处理程序(Message Handler) 1.全局消息处理程序,所有的请 ...
- EJB_开发消息驱动bean
开发消息驱动bean Java消息服务(Java MessageService) Java 消息服务(Java Message Service,简称 JMS)是用于访问企业消息系统的开发商中立的API ...
- Web API中的消息处理程序(Message Handler)
一.消息处理程序的概念 信息处理程序(Message Handler)接收HTTP请求并返回一个HTTP响应的类.Message Handler继承 HttpMessageHandler 类. 通常, ...
- Web API 源码剖析之默认消息处理程序链之路由分发器(HttpRoutingDispatcher)
Web API 源码剖析之默认消息处理程序链-->路由分发器(HttpRoutingDispatcher) 我们在上一节讲述了默认的DefaultServer(是一个类型为HttpServer的 ...
- 通过内存盘提高MSMQ的消息吞吐能力
转载:http://www.ikende.com/blog/00f2634be4704b79a3e22439edeb1343 由于MSMQ的消息交互都需要对磁盘进行读写操作,所以提高MSMQ的消息吞吐 ...
- Web API 源码剖析之默认消息处理程序链--》路由分发器(HttpRoutingDispatcher)
我们在上一节讲述了默认的DefaultServer(是一个类型为HttpServer的只读属性,详情请参考 Web API 源码剖析之全局配置).本节将讲述DefaultHandler(是一个Http ...
- EJB3.0 EJB开发消息驱动bean
(7)EJB3.0 EJB开发消息驱动bean JMS 一: Java消息服务(Java Message Service) 二:jms中的消息 消息传递系统的中心就是消息.一条 Message 由三个 ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(73)-微信公众平台开发-消息管理
系列目录 前言 回顾上一节,我们熟悉的了解了消息的请求和响应,这一节我们来建立数据库的表,表的设计蛮复杂 你也可以按自己所分析的情形结构来建表 必须非常熟悉表的结果才能运用这张表,这表表的情形涵盖比较 ...
- .net微信公众号开发——消息与事件
作者:王先荣 本文介绍如何处理微信公众号开发中的消息与事件,包括:(1)消息(事件)概况:(2)验证消息的真实性:(3)解析消息:(4)被动回复消息:(5)发送其他消息. 开源项目地址:h ...
随机推荐
- Skills CodeForces - 614D (贪心)
链接 大意: $n$门课, 第$i$门分数$a_i$, 可以增加共$m$分, 求$cnt_{mx}*cf+mi*cm$的最大值 $cnt_{mx}$为满分的科目数, $mi$为最低分, $cf$, $ ...
- The Number Games CodeForces - 980E (树, 贪心)
链接 大意: 给定$n$节点树, 求删除$k$个节点, 使得删除后还为树, 且剩余点$\sum{2^i}$尽量大 维护一个集合$S$, 每次尽量添加最大的点即可 这样的话需要支持求点到集合的最短距离, ...
- python-day39--数据库
1.什么是数据:描述事物的特征,提取对自己有用的信息 称之为数据 2..什么是数据库: 数据库即存放数据的仓库,只不过这个仓库是在计算机存储设备上,而且数据是按一定的格式存放的 为什么要用数据库: ...
- nyoj38
布线问题 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 南阳理工学院要进行用电线路改造,现在校长要求设计师设计出一种布线方式,该布线方式需要满足以下条件:1.把所有 ...
- 文件属性,获取,设置文件属性chown stat函数
转载:http://c.biancheng.net/cpp/html/326.html man 2 stat查看手册 int stat(const char *path, struct stat *b ...
- RowMapper使用
public class ABRow implements RowMapper<AABB> { private String CMC; @Override public AABB mapR ...
- Microsoft Office相关开发组件
安装office,直接引用COM控件 C#4提供对PIA引用的一种方式:链接(编译器只会将PIA中需要的部分直接嵌入到程序集中),变体(variant)被视为动态类型,以减少强制转换需要的开销: 不安 ...
- bzoj1091
题解: 暴力枚举顺序 然后计算几何 代码: #include<bits/stdc++.h> ],lp=; double v1,v2,ans=1e10; struct pos { doubl ...
- os、os.path模块中关于文件、目录常用的函数使用方法
os模块中关于文件/目录常用的函数使用方法 函数名 使用方法 getcwd() 返回当前工作目录 chdir(path) 改变工作目录 listdir(path='.') 列举 ...
- L224 词汇题
Elaborate 精心的 preparations were being made for the Prime Minister’s official visit to the four forei ...