C#实现异步消息队列

简介: 原文:C#实现异步消息队列拿到新书《.net框架设计》,到手之后迅速读了好多,虽然这本书不像很多教程一样从头到尾系统的讲明一些知识,但是从项目实战角度告诉我们如何使用我们的知识,从这本书中提炼了一篇,正好符合我前几篇的“数据驱动框架”设计的问题; 消息队列 消息队列(英语:Message queue)是一种进程间通信或同一进程的不同线程间的通信方式,软件的贮列用来处理一系列的输入,通常是来自使用者。
原文: C#实现异步消息队列

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

消息队列

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

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

实现

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

目前,有很多消息队列有很多开源的实现,包括JBoss MessagingJORAMApache ActiveMQSun Open Message QueueApache Qpid和HTTPSQS。

优点,缺点

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

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

读取队列消息

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

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

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

消息的贮存

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

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

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

上代码

建立消息对立核心队列

{
    public delegate void MessageQueueEventNotifyHandler(Message.BaseMessage message);

    public class MessageQueue:Queue
    {
        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() { 
                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();

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

目录
相关文章
|
机器学习/深度学习 数据采集 传感器
使用Python实现深度学习模型:智能空气质量监测与预测
【8月更文挑战第21天】 使用Python实现深度学习模型:智能空气质量监测与预测
1770 3
|
UED
解决Electron窗口白屏问题的预创建方案
在使用Electron创建窗口时,有时会遇到窗口显示白屏的问题。这篇文章将介绍一种解决方案,即预创建窗口,并提供了针对窗口关闭和应用退出的管理方法,以确保 Electron 应用的顺畅运行和用户体验
1240 0
|
开发框架 移动开发 前端开发
【Uniapp 专栏】Uniapp 与 React Native 的对比分析
【5月更文挑战第14天】Uniapp和React Native是热门的跨平台移动开发框架。Uniapp以其一套代码多端运行、丰富的组件生态和较低的学习曲线受到青睐,适合快速开发简单应用。React Native基于React,拥有活跃社区和优秀性能,适合复杂应用。React Native在性能上略胜一筹,尤其在需要接近原生体验的场景。Uniapp的官方组件弥补了社区资源不足。选择时需考虑开发效率、性能需求、团队技术栈和社区支持。
3426 1
【Uniapp 专栏】Uniapp 与 React Native 的对比分析
|
监控 NoSQL 程序员
C/C++程序员必备技能 ---- 内存泄漏检测
C/C++程序员必备技能 ---- 内存泄漏检测
705 0
C/C++程序员必备技能 ---- 内存泄漏检测
|
缓存 Java 网络安全
Nacos常见问题之权限认证失败如何解决
Nacos是一款易于使用的动态服务发现、配置管理和服务管理平台,针对不同版本可能出现的兼容性和功能问题,本汇总贴心整理了用户在使用Nacos时可能遇到的版本相关问题及答案,以便用户能够更顺畅地进行服务治理和配置管理。
2627 0
|
JavaScript 算法 前端开发
解密Vue 2的Diff算法:如何实现高效的DOM更新?
解密Vue 2的Diff算法:如何实现高效的DOM更新?
|
机器学习/深度学习 人工智能 自然语言处理
大模型时代下,算法工程师发展趋势及技术拓展
大模型时代下,算法工程师发展趋势及技术拓展
大模型时代下,算法工程师发展趋势及技术拓展
|
安全 C++
c++的queue在多线程下崩溃原因分析
c++的queue在多线程下崩溃原因分析
|
开发工具
matlab-如何计算信噪比
matlab-如何计算信噪比
matlab-如何计算信噪比