原文作者:虔诚者    点此传送至原文

上一篇我简单介绍了MSMQ的相关概念,本篇将以代码说明

Message

Message是MSMQ的数据存储单元,我们的用户数据一般也被填充在Message的body当中,因此很重要,让我们来看一看其在.net中的体现,如图:

在图上我们可以看见,Message提供了三个构造函数,参数body表示我们的用户数据,当我们在构造函数中传入,数据最终会被赋值给其同名属性body,参数formatter对应同名属性Formatter,它是一个序列化器,当我们的用户数据是一个复杂类型,比如类的时候Message会自动采用该序列化器将我们的复杂类型序列化。message支持3种序列化对象:

-- XMLMessageFormatter对象----MessageQueue组件的默认格式化程序设置。

-- BinaryMessageFormatter对象;

-- ActiveXMessageFormatter对象;

由于后两者格式化后的消息通常不能为人阅读,所以我们经常用到的是XMLMessageFormatter对象。该对象构造方法有三种重载:

public XmlMessageFormatter();
public XmlMessageFormatter(string[] targetTypeNames);
public XmlMessageFormatter(Type[] targetTypes);

MSMQ队列

消息(Message)需要保存在msmq队列中,.net中采用System.Messaging.MessageQueue来管理MSMQ队列,它提供能操作MSMQ的绝大多数API,比如

1.判断指定路径的队列是否存在。其中path代表队列的路径,表示形式为"主机名\队列名称",例如:".\private$\myQueue",其中"."代表本地主机,"\private$\myQueue"则代表队列的名称,"private$"表示我们创建的是专用队列,在网络上我们可以通过路径来唯一确定一个队列。

public static bool Exists(string path);

2.创建队列。path代表队列的路径,transactional表示是否创建事务队列,默认为fasle。关于事务队列我在上一篇做了详细的论述,这里不在重复。

public static MessageQueue Create(string path);
public static MessageQueue Create(string path, bool transactional);

3.删除队列

public static void Delete(string path);

4.发送消息到MSMQ。obj代表我们的用户数据,transation表示将我们的发送操作纳入事务当中。在前面我们说过MSMQ接收的是Message,但是在这里我们看到Send操作并未强制要求我们采用Message类型参数。这是因为当我传入一个Object参数数据时,在Send操作的内部自动的给我们创建了一个Message消息对象,并且将我们的传入的Object参数采用默认的序列化器序列化,然后装入Message的body属性当中,如果我们在Send方法中指定label属性,它将被赋值给Message的同名Label属性。当然我们完全可以自定义一个message对象传入Send方法中

public void Send(object obj);
public void Send(object obj, MessageQueueTransaction transaction);
public void Send(object obj, string label);

5.接收消息。同理接收消息也可以被纳入事务当中,采用Receive方法在取MSMQ的消息时,如果成功,会把MSMQ的对应消息给删除掉,并且只能取到消息队里中的排队头的消息。

public Message Receive();
public Message Receive(MessageQueueTransaction transaction);
public Message Receive(TimeSpan timeout);

如果我们想取指定标识的消息,就的采用如下的方法了,id代表消息的唯一标示。

public Message ReceiveById(string id);
public Message ReceiveById(string id, MessageQueueTransaction transaction);

如果我们在接收消息的后,不想把MSMQ队列中的消息删除怎么办呢?那么采用下面的方法吧,因为这两个方法接收MSMQ的消息,不会删除MSMQ中对应的消息,所以他们不支持事务,即没有提供事务的参数。

public Message Peek();
public Message PeekById(string id);

我们也可以一次性吧队列里面的所有消息取出来

public Message[] GetAllMessages();

实例

说了这么多,下面让我们来代码实战一下,我们采用控制台程序做测试,我把MSMQ队列做了简单的封装,如下

 

我们的用户实体也很简单,如下

 

下面我们来创建一个队列,如图我们成功的创建了"myqueue"队列

 

下面我们向队列中发送消息。如图,从图右边可以看到消息成功被加入到队列中

 

接着我们采用Peek方法接收消息(即不移除MSMQ的对应消息),很显然图中的Message依然存在MSMQ队列中

 

接着我们采用Receive方法来接收消息。这个时候我们可以很明显的看见MSMQ原来对应的消息被删除了

 

最后让我来测试,MSMQ的事务性。我们先删除我们的队列,在重新创建。我们连续向队列中插入5个消息,但是在插入第5个消息的时候我们抛出异常,如果MSMQ支持事务的话那么前面发送的4个Message将被回滚掉,MSMQ队列中应该为0个消息

 

另外值得注意的是,MSMQ的消息发送与接收,采用的是同步的方式。这样假如我们的消息队列中一个消息都没有,我们调用Receive()去接收该队列的消息会怎么样呢? 程序会被阻塞在这里,直到消息队列中有消息,程序才会接着往下走。碰到这种情况是很要命的,但是不怕MSMQ支持异步消息,由于篇幅有限我就不在多少,这里我给出一个异步操作的链接有兴趣的朋友可以去研究下,点击 这里

(转)MSMQ续的更多相关文章

  1. MSMQ(消息队列)续

    在上一篇我简单介绍了MSMQ的相关概念,本篇将以代码说明 Message Message是MSMQ的数据存储单元,我们的用户数据一般也被填充在Message的body当中,因此很重要,让我们来看一看其 ...

  2. .Net Core MVC 网站开发(Ninesky) 2.3、项目架构调整(续)-使用配置文件动态注入

    上次实现了依赖注入,但是web项目必须要引用业务逻辑层和数据存储层的实现,项目解耦并不完全:另一方面,要同时注入业务逻辑层和数据访问层,注入的服务直接写在Startup中显得非常臃肿.理想的方式是,w ...

  3. [.NET] C# 知识回顾 - 委托 delegate (续)

    C# 知识回顾 - 委托 delegate (续) [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/6046171.html 序 上篇<C# 知识回 ...

  4. iOS 开发者账号到期续费流程

    1.登录developer.apple.com,查看到期时间 2.到期提醒通知,点击Renew Membership续费(一般提前一个月提醒续费) 3.个人开发者账号续费需要支付 688人民币/年(9 ...

  5. MSMQ学习

    一.理论准备 MSMQ(MicroSoft Message Queue,微软消息队列)官方的解释是:在多个不同的应用之间实现相互通信的一种异步传输模式,相互通信的应用可以分布于同一台机器上,也可以分布 ...

  6. 微信公众号开发系列教程一(调试环境部署续:vs远程调试)

    http://www.cnblogs.com/zskbll/p/4080328.html 目录 C#微信公众号开发系列教程一(调试环境部署) C#微信公众号开发系列教程一(调试环境部署续:vs远程调试 ...

  7. 基于ajax与msmq技术的消息推送功能实现

    周末在家捣鼓了一下消息推送的简单例子,其实也没什么技术含量,欢迎大伙拍砖.我设计的这个推送demo是基于ajax长轮询+msmq消息队列来实现的,具体交互过程如下图: 先说说这个ajax长轮询,多长时 ...

  8. 已经过事务处理的 MSMQ 绑定(转载)

    https://msdn.microsoft.com/zh-cn/biztalk/ms751493 本示例演示如何使用消息队列 (MSMQ) 执行已经过事务处理的排队通信. 注意 本主题的末尾介绍了此 ...

  9. CI-持续集成(1)-软件工业“流水线”概述

    CI-持续集成(1)-软件工业“流水线”概述 1   概述 持续集成(Continuous integration)是一种软件开发实践,即团队开发成员经常集成它们的工作,通过每个成员每天至少集成一次, ...

随机推荐

  1. vs2010生成Dll文件并引用dll(C#)

    1.创建新C#控制台应用程序,项目命名createBll,打开Program.cs重命名为TestA(可以不重命名)并修改代码,如图: 写好后,可以写其它的类.cs文件 2.完成后,点击菜单栏的“项目 ...

  2. [置顶] Jquery中DOM操作(详细)

    Jquery中的DOM操作 为了能全面的讲解DOM操作,首先需要构建一个网页. HTML代码: <%@ page language="java" import="j ...

  3. Spring3.0 AOP 详解

    一.什么是 AOP. AOP(Aspect Orient Programming),也就是面向切面编程.可以这样理解,面向对象编程(OOP)是从静态角度考虑程序结构,面向切面编程(AOP)是从动态角度 ...

  4. MyEclipse10.0 安装 jbpm4.4

    马上送上地址:http://sourceforge.net/projects/jbpm/files/jBPM%204/ 偶这里下载的是 jbpm4.4 如图: 1.点击 add site 2.点击 a ...

  5. [前端JS学习笔记]JavaScript 数组

    一.JavaScript数组的奇葩 大多数语言会要求数组的元素是同个类型, 但是JavaScript允许数组元素为多种类型. var arr = ["羽毛球", 666, {&qu ...

  6. GMT、UTC、PDT 时间是什么?Linux下如何调整时区

       今天碰到一个时区配置问题,如果服务器时区配置不对,很可能在使用date相关函数时会出现莫名其妙的错误,现将相关时区说明及LINUX下调整时区方法记录如下,以做备忘. GMT GMT 是 Gree ...

  7. Smarty模板中调用PHP函数

    因为应用需要,要在Smarty中调用PHP函数,实现办法如下:模板 数据条数:{$data|count} 活动页面文件后缀:{$page|substr:'-3'} 特殊情况:{$page|str_re ...

  8. UVa784 Maze Exploration

    // 题意:输入一个迷宫,从*开始遍历,把可达点标记为字符# 注意迷宫边界不规则,要用strlen判断. #include<cstdio> #include<cstring> ...

  9. 改进uboot,添加自定义快捷菜单

    .在common目录下新增cmd_menu.c文件,内容为: #include<common.h> #include<command.h> #ifdef CONFIG_MENU ...

  10. ORACLE触发器具体解释

    ORACLE PL/SQL编程之八: 把触发器说透 本篇主要内容例如以下: 8.1 触发器类型 8.1.1 DML触发器 8.1.2 替代触发器 8.1.3 系统触发器 8.2 创建触发器 8.2.1 ...