C#实现异步消息队列
原文:C#实现异步消息队列

拿到新书《.net框架设计》,到手之后迅速读了好多,虽然这本书不像很多教程一样从头到尾系统的讲明一些知识,但是从项目实战角度告诉我们如何使用我们的知识,从这本书中提炼了一篇,正好符合我前几篇的“数据驱动框架”设计的问题;

消息队列

消息队列(英语:Message queue)是一种进程间通信或同一进程的不同线程间的通信方式,软件的贮列用来处理一系列的输入,通常是来自使用者。消息队列提供了异步的通信协议,每一个贮列中的纪录包含详细说明的资料,包含发生的时间,输入装置的种类,以及特定的输入参数,也就是说:消息的发送者和接收者不需要同时与消息队列互交。消息会保存在队列中,直到接收者取回它。

简单的说队列就是贮存了我们需要处理的Command但是并不是及时的拿到其处理结果;

实现

实际上,消息队列常常保存在链表结构中。拥有权限的进程可以向消息队列中写入或读取消息。

目前,有很多消息队列有很多开源的实现,包括JBoss Messaging、JORAM、Apache ActiveMQ、Sun Open Message Queue、Apache Qpid和HTTPSQS。

优点,缺点

消息队列本身是异步的,它允许接收者在消息发送很长时间后再取回消息,这和大多数通信协议是不同的。例如WWW中使用的HTTP协议是同步的,因为客户端在发出请求后必须等待服务器回应。然而,很多情况下我们需要异步的通信协议。比如,一个进程通知另一个进程发生了一个事件,但不需要等待回应。但消息队列的异步特点,也造成了一个缺点,就是接收者必须轮询消息队列,才能收到最近的消息。

和信号相比,消息队列能够传递更多的信息。与管道相比,消息队列提供了有格式的数据,这可以减少开发人员的工作量。但消息队列仍然有大小限制。

读取队列消息

主要有两种(1)服务端的推;(2)客户端的拉;

拉:主要是客户端定时轮询拿走消息处理;

推:通过事件订阅方式主动通知订阅者进行处理;

消息的贮存

简单的是通过内存链表实现贮存;也可以借助DB,比如Redis;还可以持久到本地文件中;

如何保证异步处理的一致性

尽管队列主要目的是实现消息贮存,同时将调用与实现异步化。但是如果想达到处理消息一致性,好的方式是区别业务处理顺序,比如操作主从DB,主负责写,从负责读,我们没有机会在写之后立马从读数据库拿到你想要的结果;同时我们需要借助中间状态,当多个中间状态同时符合调用结果才到到业务时间被处理,否则将“异常消息”持久化,待下次操作;

上代码

建立消息对立核心队列

{public delegate void MessageQueueEventNotifyHandler(Message.BaseMessage message);public class MessageQueue:Queue<BaseMessage>{public static MessageQueue GlobalQueue = new MessageQueue();private Timer timer = new Timer();public MessageQueue() {this.timer.Interval = 5000;this.timer.Elapsed += Notify;this.timer.Enabled = true;}private void Notify(object sender, ElapsedEventArgs e) {lock (this) {if (this.Count > 0) {//this.messageNotifyEvent.GetInvocationList()[0].DynamicInvoke(this.Dequeue());var message = this.Dequeue();this.messageNotifyEvent(message);}}}private MessageQueueEventNotifyHandler messageNotifyEvent;public event MessageQueueEventNotifyHandler MessageNotifyEvent {add {this.messageNotifyEvent += value;}remove {if (this.messageNotifyEvent != null) {this.messageNotifyEvent -= value;}}}}
}

事件处理

public const string OrderCodePrefix = "P";public void Submit(Message.BaseMessage message){Order order = message.Body as Order;if (order.OrderCode.StartsWith(OrderCodePrefix)){System.Console.WriteLine("这个是个正确的以({0})开头的订单:{1}", OrderCodePrefix,order.OrderCode);}else {System.Console.WriteLine("这个是个错误的订单,没有以({0})开头:{1}",OrderCodePrefix,order.OrderCode);}}

可依据具体业务进行个性化处理;

通过Proxy向队列追加消息

public class OrderServiceProxy:IOrderService{public void Submit(Message.BaseMessage message){MessageQueue.MessageQueue.GlobalQueue.Enqueue(message);}}

客户端调用

OrderService orderService = new OrderService();MessageQueue.MessageQueue.GlobalQueue.MessageNotifyEvent += orderService.Submit;var orders = new List<Order>() { new Order(){OrderCode="P001"},new Order(){OrderCode="P002"},new Order(){OrderCode="B003"}};OrderServiceProxy proxy = new OrderServiceProxy();orders.ForEach(order => proxy.Submit(new Message.BaseMessage() { Body=order}));Console.ReadLine();

这样就满足了事件的绑定与触发个性化处理,同时达到了消息异步化的目的,希望更细致的拓展用到后期的项目中。

posted on 2015-02-02 08:35 NET未来之路 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/lonelyxmas/p/4266740.html

C#实现异步消息队列相关推荐

  1. 八.利用springAMQP实现异步消息队列的日志管理

    经过前段时间的学习和铺垫,已经对spring amqp有了大概的了解.俗话说学以致用,今天就利用springAMQP来完成一个日志管理模块.大概的需求是这样的:系统中有很多地方需要记录操作日志,比如登 ...

  2. redis stream java消息队列_Redis 异步消息队列与延时队列

    消息中间件,大家都会想到 Rabbitmq 和 Kafka 作为消息队列中间件,来给应用程序之间增加异步消息传递功能.这两个中间件都是专业的消息队列中间件,特性之多超出了大多数人的理解能力.但是这种属 ...

  3. Redis异步消息队列

    一.异步消息队列介绍 个人认为消息队列的主要特点是异步处理,主要目的是减少请求响应时间和解耦.所以主要的使用场景就是将比较耗时而且不需要即时(同步)返回结果的操作作为消息放入消息队列.同时由于使用了消 ...

  4. 异步消息队列Celery

    Celery是异步消息队列, 可以在很多场景下进行灵活的应用.消息中包含了执行任务所需的的参数,用于启动任务执行, suoy所以消息队列也可以称作 在web应用开发中, 用户触发的某些事件需要较长事件 ...

  5. Celery + Flower + FastAPI + RabbitMQ ,Python实现异步消息队列和监控

    @Author:Runsen 消息队列 消息队列让应用程序在用户请求之外异步执行称为任务的工作.如果应用程序需要在后台执行工作,它会将任务添加到任务队列中.这些任务稍后由工作服务执行. Celery ...

  6. Spring framework(10):集成 JMS 异步消息队列(ActiveMQ)

    JMS 和 Apache-ActiveMQ 简介 JMS(Java Message Service,Java 消息服务)是一个 Java 面向消息中间件(MOM)的 API,用于 Java 应用程序或 ...

  7. php消息队列异步,消息队列 - 如何实现php的异步任务队列

    在开发一个类微博系统,采用推模式,用户发一条微博,需要将此微博在其所有粉丝每人的"收件箱"中存一条,如果粉丝数量大,处理过程就会很耗时,想把这个逻辑用异步队列来实现. 思路如下: ...

  8. 异步消息队列zeromq实现服务器间高性能通信

    ZeroMQ 是一个很有个性的项目,它原来是定位为"史上最快消息队列",所以名字里面有"MQ"两个字母,但是后来逐渐演变发展,慢慢淡化了消息队列的身影,改称为消 ...

  9. 使用redis实现异步消息队列

    实现InitializingBean.AppalicationContextAware 接口. 在Spring加载EventConsumer类并且实例化之后,调用此方法,初始化config属性

最新文章

  1. 试过不用循环语句撸代码吗?
  2. ECCV 2020 | 腾讯优图8篇论文入选,涵盖目标跟踪、行人重识别、人脸识别等领域...
  3. PHP和mysql的长连接
  4. Spring 学习04
  5. C#格式化字符串净化代码的方法
  6. 保护眼睛的电脑设置_干货,怎么设置显示器,才能保护好我们的眼睛?
  7. spearman相关性分析_「同学交大经金考研」西安交通大学432统计学-必考简答题4:spearman等级相关系数...
  8. 数字int转换成文字string形式的方法
  9. 一个普通摄像头就能让二次元老婆“活”过来,网友:求收费
  10. Java二十三设计模式之-----桥接模式
  11. 10个经典Python爬虫入门实例!你还不知道吗
  12. Xcode打包ipa基本步骤
  13. 三角肌前束(02):哑铃交替前举
  14. Docker学习,这一篇博客就够了
  15. C语言实验:打印日历
  16. C++类的成员函数(在类外定义成员函数)
  17. 掌银环境 和 微信浏览器 图片变形问题
  18. 技术干货:工欲善其事,必先利其器 阿里云数据库系列谈之一
  19. 分享两款不错的CRM客户关系管理系统源码
  20. ipv6默认网关怎么打开。有偿。

热门文章

  1. Python3引号创建字符串
  2. Storm单节点部署及启动
  3. Python Django 迁移失败如何处理
  4. 【视频】vue指令之v-if、v-bind
  5. MySQL服务启动及密码设置/配置远程访问
  6. SpringBoot集成Eureka导致返回结果由json变为xml解决方案
  7. play!framework框架概述
  8. Spring AOP编程-传统基于aspectJ切点AOP开发
  9. 如何使用python效率办公_日常office工作中如何用python提升效率014
  10. 设计模式的理解: 代理模式(Proxy)