上一篇:消息队列介绍

本篇一开始就上代码,主要演练MessageQueue的实际应用。用户提交订单(消息发送),系统将订单发送到订单队列(Order Queue)中;订单管理系统(消息接收)端,监听消息队列,收到新的消息就显示在订单列表中,用户可以处理订单。原创(每行代码皆为自己手敲的)

1、提交课程订单

    public partial class Form1 : Form
{
// author:fjzhang 2017-08-01
public Form1()
{
InitializeComponent();
}
/// <summary>
/// 提交订单按钮
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnSubmit_Click(object sender, EventArgs e)
{
try
{
//实例一个课程订单对象
var order = new CourseOrder();
//订单信息
order.Course = new Course()
{
Title = comboBoxCourse.SelectedItem.ToString()
};
//顾客信息
order.Customer = new Customer()
{
Company = textBoxCompany.Text,
Contact = textBoxContact.Text
};
//实例一个队列对象
using (var queue = new MessageQueue(CourseOrder.CourseOrderQueueName))
{
//实例一个消息对象
using (var message = new System.Messaging.Message(order))
{
//设置优先级
if (checkBoxPriority.CheckState == CheckState.Checked)
{
message.Priority = MessagePriority.High;
}
//设置消息可以恢复
message.Recoverable = true;
//发送消息
queue.Send(order, string.Format("课程订单[{0}]", order.Customer.Company));
}
}
//提示订单提交成功
MessageBox.Show("订单提交成功!", "课程订单", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (MessageQueueException ex)
{
//提示异常信息
MessageBox.Show(ex.Message, "异常提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}

2、处理课程订单

    /// <summary>
/// 订单处理界面 author:fjzhang 2017-08-01
/// </summary>
public partial class Form1 : Form
{
/// <summary>
/// 订单队列
/// </summary>
private MessageQueue orderQueue;
/// <summary>
/// 构造函数,初始化界面窗体,监听订单队列
/// </summary>
public Form1()
{
InitializeComponent();
//队列名称
string queueName = CourseOrder.CourseOrderQueueName;
//初始化订单队列
orderQueue = new MessageQueue(queueName);
//设置消息类型
orderQueue.Formatter = new XmlMessageFormatter(new Type[] {
typeof(CourseOrder),
typeof(Customer),
typeof(Course)
});
//在未收到订单之前,不启用处理订单按钮
btnProcessOrder.Enabled = false;
//开始监听订单队列
Task t1 = new Task(PeekMessages);
t1.Start();
}
/// <summary>
/// 监听订单队列(如果收到新订单,就在订单列表显示出来)
/// </summary>
private void PeekMessages()
{
//使用消息队列枚举器来显示队列的所有消息
using (MessageEnumerator messagesEnumerator = orderQueue.GetMessageEnumerator2())
{
//检查队列中是否有新消息。如果没有消息,就等待队列的新消息,这里设置等待3小时后才退出。
while (messagesEnumerator.MoveNext(TimeSpan.FromHours(3)))
{
//这里的LaBELIdMapping是我自己定义的,就两字String类型的字段(Id,Label)
var lableId = new LabelIdMapping()
{
Id = messagesEnumerator.Current.Id,
Label = messagesEnumerator.Current.Label
};
//使用主线程执行新增收到订单行
this.Invoke(new EventHandler(delegate
{
AddListItem(lableId);
}));
}
//提示等待3小时还没有新消息进队列
MessageBox.Show("三小时内没有订单", "退出提醒", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
/// <summary>
/// 在订单列表新增一项
/// </summary>
/// <param name="labelIdMapping"></param>
private void AddListItem(LabelIdMapping labelIdMapping)
{
//在listBox控件中新增一行
listBox1.Items.Add(labelIdMapping);
}
/// <summary>
/// 处理订单
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnProcessOrder_Click(object sender, EventArgs e)
{
LabelIdMapping labelId = listBox1.SelectedItem as LabelIdMapping;
var message = orderQueue.ReceiveById(labelId.Id);
listBox1.Items.Remove(labelId);
listBox1.SelectedIndex = -1;
btnProcessOrder.Enabled = false;
textBoxCourse.Text = string.Empty;
textBoxCompany.Text = string.Empty;
textBoxContact.Text = string.Empty;
MessageBox.Show(string.Format("订单[{0}]处理成功", labelId.Label), "订单管理", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
/// <summary>
/// 选中消息列表某一行(订单)执行事件(查看订单详情)
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
LabelIdMapping labelId = listBox1.SelectedItem as LabelIdMapping;
if (labelId == null)
return;
orderQueue.MessageReadPropertyFilter.Priority = true;
var message = orderQueue.PeekById(labelId.Id);
CourseOrder order = message.Body as CourseOrder;
if (order != null)
{
textBoxCourse.Text = order.Course.Title;
textBoxCompany.Text = order.Customer.Company;
textBoxContact.Text = order.Customer.Contact;
btnProcessOrder.Enabled = true; if (message.Priority > MessagePriority.Normal)
{
labelPriority.Text = "高优先级";
}
else
{
labelPriority.Text = "--";
}
}
else
{
MessageBox.Show("当前选中的不是课程订单", "订单管理", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
}

3、效果

以上就是今天实现的全部代码,主要实现了消息的发送和消息的接收,代码写了注释。有不足的地方,上一篇写到消息有几种类型,其中有两种“确认消息”和“响应消息”还没有演示,后面再写一篇应用“确认消息”和“响应消息”。

消息队列第二篇:MessageQueue实战(课程订单)的更多相关文章

  1. Java中常用的七个阻塞队列第二篇DelayQueue源码介绍

    Java中常用的七个阻塞队列第二篇DelayQueue源码介绍 通过前面两篇文章,我们对队列有了了解及已经认识了常用阻塞队列中的三个了.本篇我们继续介绍剩下的几个队列. 本文主要内容:通过源码学习De ...

  2. 消息队列第一篇:MessageQueue介绍

    消息队列有哪些好处或功能: 1.消息可以在断开连接的环境下发送.不需要同时运行正在发送和正在接收的应用程序. 2.使用快捷模式,消息可以非常快地发送.在快捷模式下,消息存储在内存中. 3.对于可恢复的 ...

  3. RabbitMQ消息队列入门篇(环境配置+Java实例+基础概念)

    一.消息队列使用场景或者其好处 消息队列一般是在项目中,将一些无需即时返回且耗时的操作提取出来,进行了异步处理,而这种异步处理的方式大大的节省了服务器的请求响应时间,从而提高了系统的吞吐量. 在项目启 ...

  4. 消息队列-一篇读懂rabbitmq(生命周期,confirm模式,延迟队列,集群)

    什么是消息队列? 就是生产者生产一条消息,发送到这个rabbitmq,消费者连接rabbitmq并且进行消费,生产者和消费者并需要知道对方是如何工作的,从而实现程序之间的解耦,异步和削峰,这也就是消息 ...

  5. 鸿蒙内核源码分析(消息队列篇) | 进程间如何异步传递大数据 | 百篇博客分析OpenHarmony源码 | v33.02

    百篇博客系列篇.本篇为: v33.xx 鸿蒙内核源码分析(消息队列篇) | 进程间如何异步传递大数据 | 51.c.h .o 进程通讯相关篇为: v26.xx 鸿蒙内核源码分析(自旋锁篇) | 自旋锁 ...

  6. 线程安全使用(四) [.NET] 简单接入微信公众号开发:实现自动回复 [C#]C#中字符串的操作 自行实现比dotcore/dotnet更方便更高性能的对象二进制序列化 自已动手做高性能消息队列 自行实现高性能MVC WebAPI 面试题随笔 字符串反转

    线程安全使用(四)   这是时隔多年第四篇,主要是因为身在东软受内网限制,好多文章就只好发到东软内部网站,懒的发到外面,现在一点点把在东软写的文章给转移出来. 这里主要讲解下CancellationT ...

  7. ASP.NET Core消息队列RabbitMQ基础入门实战演练

    一.课程介绍 人生苦短,我用.NET Core!消息队列RabbitMQ大家相比都不陌生,本次分享课程阿笨将给大家分享一下在一般项目中99%都会用到的消息队列MQ的一个实战业务运用场景.本次分享课程不 ...

  8. 跟我一起学WCF(1)——MSMQ消息队列

    一.引言 Windows Communication Foundation(WCF)是Microsoft为构建面向服务的应用程序而提供的统一编程模型,该服务模型提供了支持松散耦合和版本管理的序列化功能 ...

  9. 【MQ】消息队列及常见MQ比较

    一.什么是消息队列 我们可以把消息队列比作是一个存放消息的容器,当我们需要使用消息的时候可以取出消息供自己使用.消息队列是分布式系统中重要的组件,使用消息队列主要是为了通过异步处理提高系统性能和削峰. ...

随机推荐

  1. GoLang 命令

    目录 查看可用命令 build 和 run 命令 go build编译时的附加参数 clent命令 fmt 和 doc 命令 get 命令 远程包的路径格式 go get+远程包 go get使用时的 ...

  2. Verilog_Day2

    Verilog_Day1 在CSDN博客上.http://blog.csdn.net/m0_38073085 第三章: 书上基本知识 每个Verilog程序包括4个主要部分:端口定义,I/O说明,内部 ...

  3. 批量分离SQL数据库语句

    --sp_helpdb--查看可用数据库 declare @name sysname, @sql nvarchar(4000) DECLARE roy CURSOR FOR --排除不分离的数据库名就 ...

  4. IPC学习

    课下作业-IPC 要求: 研究Linux下IPC机制:原理,优缺点,每种机制至少给一个示例,提交研究博客的链接 共享内存 管道 FIFO 信号 消息队列 共享内存 共享内存可以说是最有用的进程间通信方 ...

  5. 洛谷 P2563 [AHOI2001]质数和分解

    洛谷  P2563 [AHOI2001]质数和分解 题目描述 任何大于 1 的自然数 n 都可以写成若干个大于等于 2 且小于等于 n 的质数之和表达式(包括只有一个数构成的和表达式的情况),并且可能 ...

  6. 06 django的用户认证组件

    1.用户认证组件 用户认证组件: 功能:用session记录登录验证状态 前提:用户表:django自带的auth_user 创建超级用户: python3 manage.py createsuper ...

  7. cogs1799 [国家集训队2012]tree(伍一鸣)

    LCT裸题 注意打标记之间的影响就是了 这个膜数不会爆unsigned int #include<cstdio> #include<cstdlib> #include<a ...

  8. postMan测试Controller接口

    1.介绍 Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件. 2.安装 Postman 4.1.2 下载地址: http://files.cnblogs.com/file ...

  9. hdu2544最短路(dijkstra)

    传送门 dijkstra #include<bits/stdc++.h> using namespace std; const int INF=0x3f3f3f3f; ; int dist ...

  10. static笔记

    目录 1. static概括 2. static特点 1. 被static修饰的成员变量属于类,不属于这个类的某个对象. 2.被static修饰的成员可以并且建议通过类名直接访问 3. static注 ...