代码:

namespace RabbitMQDemo
{
public partial class WorkQueues : Form
{
private string queueName = "WorkQueues_queue";
Action<string, TextBox> SetText;
private readonly static WorkQueues _WorkQueues;
static WorkQueues()
{
_WorkQueues = new WorkQueues();
}
/// <summary>
/// 单例模式
/// </summary>
public static WorkQueues SingleForm { get { return _WorkQueues; } }
private WorkQueues()
{
CheckForIllegalCrossThreadCalls = false;
InitializeComponent();
ReceiveMsg(txtConsumer1);//消费者1
ReceiveMsg(txtConsumer2);//消费者2
SetText += OnSetText;
} private void btnSendMsg_Click(object sender, EventArgs e)
{
SendMsg();
}
/// <summary>
/// 发送消息
/// </summary>
private void SendMsg()
{
string message = txtPublisher.Text;
if (message.Trim().Length <= )
{
MessageBox.Show("请输入要发送的消息");
}
var factory = new ConnectionFactory() { HostName = "localhost" };
using (var connection = factory.CreateConnection())
using (var channel = connection.CreateModel())
{
//durable-队列持久化,为true的时候告诉rabbitmq不管服务器停止运行还是崩溃或重启都不能丢失队列queue(已经声明过的队列无法再重新定义durable的值,如果这样做了,服务器会返回一个错误)
channel.QueueDeclare(queue: queueName,
durable: true,
exclusive: false,
autoDelete: false,
arguments: null); var body = Encoding.UTF8.GetBytes(message); //消息持久化-为true的时候告诉rabbitmq不管服务器停止运行还是崩溃或重启都不能丢失队列queue,这种消息持久化方式不能保证消息永不丢失,它告诉rabbitmq将消息保存到磁盘,但是当rabbitmq接收到消息但是还没有保存的时候有一个很短的时间窗口.此外,rabbitmq不会为每个消息执行fsync(2)-它可能只是保存到缓存中,而不是真正的写入磁盘.这种消息持久化方式保证不强,用于要求不那么严格的任务队列,已经足够,如果要更完善的消息持久化,可以使用publisher confirms
var properties = channel.CreateBasicProperties();
properties.Persistent = true; channel.BasicPublish(exchange: "",
routingKey: queueName,
basicProperties: properties,
body: body);
}
}
/// <summary>
/// 接收消息
/// </summary>
private void ReceiveMsg(TextBox box)
{
try
{
var factory = new ConnectionFactory() { HostName = "localhost" };
var connection = factory.CreateConnection();
var channel = connection.CreateModel(); channel.QueueDeclare(
queue: queueName,
durable: true,
exclusive: false,
autoDelete: false,
arguments: null); //公平分发
//默认情况下rabbitmq会将消息平均地发给消费者,不管消费者是否正在处理消息,也不会考虑消费者是否返回未确认消息,这会造成资源浪费.假如队列中有10条消息,有2个消费者,那么每个消费者会收到5条消息,如果说其中5条消息是要花费大量时间的,并且这5条消息都刚好发送给了第一个消费者,那么第1个消费者将会一直处于忙碌状态,而第二个消费者假如处理的另外5条消息都不花费多少时间那么第二个消费者就会闲置.prefetchCount=1告诉rabbitmq不要向我发送新的消息,直到我处理并确认了前一个消息,然后rabbitmq将会把消息发给下一个消费者
//假如所有的消费者都处于忙碌状态(没有反馈消息确认给rabbitmq)那么消息将在队列中排队等待,这可能造成queue存储空间不足,需要采取预防措施
channel.BasicQos(
prefetchSize: ,
prefetchCount: ,
global: false); var consumer = new EventingBasicConsumer(channel);
consumer.Received += (model, ea) =>
{
var msg = Encoding.UTF8.GetString(ea.Body); //要求发送的消息包含'.',每个'.'让线程花1秒时间处理,10个花10秒
int dots = msg.Split('.').Length - ;
Thread.Sleep(dots * ); //将消息显示在界面上
box.Invoke(SetText, msg, box); //手动想rabbitmq发送消息确认
channel.BasicAck(
deliveryTag: ea.DeliveryTag,
multiple: false);
}; //消息确认
//noAck-自动回复消息 为true的时候consumer收到了一个消息就会立刻返回一个标记给rabbitmq告诉它这个消息我已经拿到了,你可以自由的删除掉它,至于consumer怎么处理这个消息或者处理的过程中出错了在rabbitmq中将找不回这个消息(使用这种方式要确保consumer不会挂掉,否则消息容易丢失)
channel.BasicConsume(
queue: queueName,
noAck: false,
consumer: consumer);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
} private void OnSetText(string text, TextBox box)
{
box.Text += string.Format("{0}\r\n", text);
}
}
}

界面:

大概流程:

生产者发送一条消息,如果消息包含英文句点'.',那么每一个句点标识消费者处理这条消息要花费的时间,这个时候该消费者就不再接收来自rabbitmq的消息,rabbitmq将会把消息发给下一个消费者以保证不会有消费者要么一直忙碌要么一直闲置的bug,同时要注意的是,一旦一个消息发送给了一个消费者另一个消费者就得不到这条消息,只能拿到下一条

测试结果:

WinForm实现Rabbitmq官网6个案例-Work Queues的更多相关文章

  1. WinForm实现Rabbitmq官网6个案例-RPC

    获取源码 客户端代码: namespace RabbitMQDemo { public partial class RPC : Form { private readonly static RPC _ ...

  2. WinForm实现Rabbitmq官网6个案例-Publishe/Subscribe

    代码: namespace RabbitMQDemo { public partial class PublishSubscribe : Form { private string exchangeN ...

  3. WinForm实现Rabbitmq官网6个案例-Hello World

    先上代码 namespace RabbitMQDemo { public partial class HelloWorld : Form { string queueName1 = "hel ...

  4. WinForm实现Rabbitmq官网6个案例-Topics

    代码: namespace RabbitMQDemo { public partial class Topics : Form { private string exchangeName = &quo ...

  5. WinForm实现Rabbitmq官网6个案例-Routing

    代码: namespace RabbitMQDemo { public partial class Routing : Form { private string exchangeName = &qu ...

  6. 官网英文版学习——RabbitMQ学习笔记(一)认识RabbitMQ

    鉴于目前中文的RabbitMQ教程很缺,本博主虽然买了一本rabbitMQ的书,遗憾的是该书的代码用的不是java语言,看起来也有些不爽,且网友们不同人学习所写不同,本博主看的有些地方不太理想,为此本 ...

  7. 2022年官网下安装RabbitMQ最全版与官网查阅方法

    目录 一.Erlang环境部署 1.百度搜索"Erlang",或者访问网址:https://www.erlang.org/,找到DOWNLOAD双击进入. 2.找到支持的windo ...

  8. Yeoman 官网教学案例:使用 Yeoman 构建 WebApp

    STEP 1:设置开发环境 与yeoman的所有交互都是通过命令行.Mac系统使用terminal.app,Linux系统使用shell,windows系统可以使用cmder/PowerShell/c ...

  9. MXNet官网案例分析--Train MLP on MNIST

    本文是MXNet的官网案例: Train MLP on MNIST. MXNet所有的模块如下图所示: 第一步: 准备数据 从下面程序可以看出,MXNet里面的数据是一个4维NDArray. impo ...

随机推荐

  1. 使用Chrome-headless模式下,截屏不全屏的问题

    在headless模式下,是没有打开浏览器窗口的,那么driver.maximize_window(),找不到目标也打不开. 我们可以换一种方式,去在无头模式下,指定浏览器的窗口大小运行即可. __o ...

  2. 解压命令tar zxvf中zxvf的意思

    x : 从 tar 包中把文件提取出来 z : 表示 tar 包是被 gzip 压缩过的,所以解压时需要用 gunzip 解压 v : 显示详细信息 f xxx.tar.gz : 指定被处理的文件是 ...

  3. Python 全栈开发:dict(字典)常用方法操作、dict嵌套

    数据类型的划分:可变数据类型和不可变数据类型. 不可变数据类型(可哈希):元祖.bool.int.str 可变数据类型(不可哈希):list.dict,set(集合) dict(字典): dict(字 ...

  4. ThreadLocal系列(三)-TransmittableThreadLocal的使用及原理解析

    ThreadLocal系列(三)-TransmittableThreadLocal的使用及原理解析 上一篇:ThreadLocal系列(二)-InheritableThreadLocal的使用及原理解 ...

  5. 使用Vue写一个登陆页面并在管理页面查看和修改

    注册页面代码如下html <!DOCTYPE html> <html lang="en"> <head> <meta charset=&q ...

  6. Mac下截图工具

    苹果系统自带截图功能 1.截取全屏:快捷键(Shift+Command+3) ▲直接按“Shift+Command+3“快捷键组合,即可截取电脑全屏,图片自动保存在桌面. 2.截图窗口:快捷键(Shi ...

  7. (转)Mysql占用过高CPU时的优化手段

    Mysql占用CPU过高的时候,该从哪些方面下手进行优化?占用CPU过高,可以做如下考虑:1)一般来讲,排除高并发的因素,还是要找到导致你CPU过高的哪几条在执行的SQL,show processli ...

  8. vSphere虚拟主机安装Centos7系统

    经过上一帖的主机设置,这一步就可以开始安装系统了,本次详细记录各个过程并分析结果. Centos7 1.右键点击列表中的虚拟主机,打开控制台. 点击绿色开机键,开始安装. 这里有一个很关键的点,就是上 ...

  9. hibernate_SessionFactory_getCurrentSession_JTA简介

    JTA:java transaction  api java里所规定的一种管理事务的API 在另一篇播客我写到了,SessionFactory需要关注两个方法, 即:  openSession     ...

  10. 对于SQL Server 2008删除或压缩数据库日志的方法

    由于数据库日志增长被设置为“无限制”,所以时间一长日志文件必然会很大,一个400M的数据库居然有4G的LOG文件,严重占用了磁盘空间.由于主要是做OLAP,所以数据库本身不会有大变动,所以日志也就没有 ...