消息队列第二篇:MessageQueue实战(课程订单)
本篇一开始就上代码,主要演练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实战(课程订单)的更多相关文章
- Java中常用的七个阻塞队列第二篇DelayQueue源码介绍
Java中常用的七个阻塞队列第二篇DelayQueue源码介绍 通过前面两篇文章,我们对队列有了了解及已经认识了常用阻塞队列中的三个了.本篇我们继续介绍剩下的几个队列. 本文主要内容:通过源码学习De ...
- 消息队列第一篇:MessageQueue介绍
消息队列有哪些好处或功能: 1.消息可以在断开连接的环境下发送.不需要同时运行正在发送和正在接收的应用程序. 2.使用快捷模式,消息可以非常快地发送.在快捷模式下,消息存储在内存中. 3.对于可恢复的 ...
- RabbitMQ消息队列入门篇(环境配置+Java实例+基础概念)
一.消息队列使用场景或者其好处 消息队列一般是在项目中,将一些无需即时返回且耗时的操作提取出来,进行了异步处理,而这种异步处理的方式大大的节省了服务器的请求响应时间,从而提高了系统的吞吐量. 在项目启 ...
- 消息队列-一篇读懂rabbitmq(生命周期,confirm模式,延迟队列,集群)
什么是消息队列? 就是生产者生产一条消息,发送到这个rabbitmq,消费者连接rabbitmq并且进行消费,生产者和消费者并需要知道对方是如何工作的,从而实现程序之间的解耦,异步和削峰,这也就是消息 ...
- 鸿蒙内核源码分析(消息队列篇) | 进程间如何异步传递大数据 | 百篇博客分析OpenHarmony源码 | v33.02
百篇博客系列篇.本篇为: v33.xx 鸿蒙内核源码分析(消息队列篇) | 进程间如何异步传递大数据 | 51.c.h .o 进程通讯相关篇为: v26.xx 鸿蒙内核源码分析(自旋锁篇) | 自旋锁 ...
- 线程安全使用(四) [.NET] 简单接入微信公众号开发:实现自动回复 [C#]C#中字符串的操作 自行实现比dotcore/dotnet更方便更高性能的对象二进制序列化 自已动手做高性能消息队列 自行实现高性能MVC WebAPI 面试题随笔 字符串反转
线程安全使用(四) 这是时隔多年第四篇,主要是因为身在东软受内网限制,好多文章就只好发到东软内部网站,懒的发到外面,现在一点点把在东软写的文章给转移出来. 这里主要讲解下CancellationT ...
- ASP.NET Core消息队列RabbitMQ基础入门实战演练
一.课程介绍 人生苦短,我用.NET Core!消息队列RabbitMQ大家相比都不陌生,本次分享课程阿笨将给大家分享一下在一般项目中99%都会用到的消息队列MQ的一个实战业务运用场景.本次分享课程不 ...
- 跟我一起学WCF(1)——MSMQ消息队列
一.引言 Windows Communication Foundation(WCF)是Microsoft为构建面向服务的应用程序而提供的统一编程模型,该服务模型提供了支持松散耦合和版本管理的序列化功能 ...
- 【MQ】消息队列及常见MQ比较
一.什么是消息队列 我们可以把消息队列比作是一个存放消息的容器,当我们需要使用消息的时候可以取出消息供自己使用.消息队列是分布式系统中重要的组件,使用消息队列主要是为了通过异步处理提高系统性能和削峰. ...
随机推荐
- CBrother异或加密与C++异或加密函数
CBrother脚本异或加密与C++异或加密函数 异或对于数据加密来说是最简单的方式,在一般的安全性要求不是非常高的地方,异或加密是最好的选择. C++异或加密代码 int g_PWD = 0xffe ...
- JavaEE笔记(八)
第一个Spring Student(学生) bean package com.my.bean; import java.io.Serializable; public class Student im ...
- mfc 函数模板
函数模板的使用 一. 函数模板的使用 使用函数模板可以简化 形参个数相同,而类型不同的函数. template<typename T> //可以用class替换typename int m ...
- 柯朗微积分与数学分析习题选解(1.2 节 d)
一直在读<陶哲轩实分析>,陶的书非常的严谨,环环相扣,但是也有个缺点就是计算性的例子和应用方面的例子太少了.所以就又找了本柯朗的<微积分与数学分析>搭配着看.柯朗的书的习题与陶 ...
- 1433: [ZJOI2009]假期的宿舍
1433: [ZJOI2009]假期的宿舍 链接 分析: 直接网络流,看是否满足即可. S向每个有需要的人连边,有床的向T连边,认识的人之间互相连边. 代码: #include<cstdio&g ...
- 牛客网NOIP赛前集训营-提高组(第六场)B-选择题[背包]
题意 题目链接 分析 直接背包之后可以 \(O(n)\) 去除一个物品的影响. 注意特判 \([p==1]\) 的情况. 总时间复杂度为 \(O(n^2)\) . 代码 #include<bit ...
- MYSQL创建表的约束条件(可选)
一.常用的一些约束条件 一.创建表的完整语法1.创建表的万能模板:create table 库名.表名( 字段名1 类型[(宽度) 约束条件], 字段名2 类型[(宽度) 约束条件], 字段名3 类型 ...
- 【转载】钉钉开发c#帮助类 获取用户信息 DingHelper.cs
using System;using System.Collections.Generic;using System.Configuration;using System.Linq;using Sys ...
- 一句话打印'*'图案(列表推导式, 人生苦短, 我用Python)
```python # coding=utf-8 print ('\n'.join(['*'*6 for i in range(4)])) # ****** # ****** # ****** # * ...
- Netty源码分析第4章(pipeline)---->第6节: 传播异常事件
Netty源码分析第四章: pipeline 第6节: 传播异常事件 讲完了inbound事件和outbound事件的传输流程, 这一小节剖析异常事件的传输流程 首先我们看一个最最简单的异常处理的场景 ...