C# 实现 Actor并发模型 (案例版)

啥是Actor模型

Actor (英语翻译 演员) 这个概念要回溯到面向对象程序设计的本身上来,更偏向于现实世界,现实世界就是由单个个体(人)与其他个体或(人)通讯(消息)组成的现实世界,所以,它的好处是显而易见的,生活就是Actor。

现有的面向对象编程模型是基于内存共享线程模型的,而Actor是基于消息模型的,Actor 之间是完全隔离的,不会共享任何变量。

基于内存,那么,内存会溢出,异常,基于消息的话,则没有这种困扰。

又由于它变相的来讲是单线程的,自己处理自己的事务,又实现了与其他业务的隔离。

Erlang语言,天生支持Actor模型,是一个好语言啊。

Actor 的优势

  1. 1. Actor不共享状态

  2. 2. 高并发,无锁(无共享状态)

  3. 3. Actor效率高(同一时刻只处理一个任务,属于单线程处理)

Actor 框架有

  1. 1. Orleans

  2. 2. Dapr

  3. 3. Akka.NET

  4. 4. Proto.Actor

Actor模型的实现

为啥要实现Actor模型,一个是为了更深入的了解它,一个是想实现一下。

可能在某些地方直接就用了。没必要搞那么复杂引用。

Actor模型的原理

按照自己的理解画了一下。

1529d64a695186c7555fb6f48d507e2b.png

简单来讲,就是各个服务都可以投递消息到Actor实例里,Actor会从邮箱里把消息取出来,然后,消费掉。这么简单的一件事情。

Actor 代码逻辑的实现

IActor.cs

/// <summary>
/// 无锁并行编程模型(暂时用来处理串行任务,任务串行执行)
/// </summary>
public interface IActor
{/// <summary>/// 增加消息/// </summary>/// <returns></returns>bool AddMsg(object message);/// <summary>/// 启动服务/// </summary>/// <returns></returns>Task Start();/// <summary>/// 停止服务运行,等待毫秒数/// </summary>/// <param name="WatingTimeout"></param>/// <returns></returns>bool Stop(int WatingTimeout);
}

Actor.cs

/// <summary>
/// Actor抽象
/// </summary>
public abstract class Actor : IDisposable, IActor
{public Actor(string name){Name = name;MailBox = new BlockingCollection<object>();}/// <summary>/// 名称/// </summary>public string Name { get; set; }/// <summary>/// 是否启用/// </summary>public bool Active { get; private set; }/// <summary>/// 是否长时间运行。长时间运行任务使用独立线程,默认true/// </summary>public bool LongRunning { get; set; } = true;/// <summary>/// 处理的消息邮箱/// </summary>public BlockingCollection<object> MailBox { get; set; }/// <summary>/// 内置任务/// </summary>private Task _task;public virtual Task Start(){if (Active) return _task;Active = true;// 启动异步if (_task == null){lock (this){if (_task == null){_task = Task.Factory.StartNew(DoActorWork, LongRunning ? TaskCreationOptions.LongRunning : TaskCreationOptions.None);}}}return _task;}public virtual bool Stop(int WatingTimeout = 100){MailBox?.CompleteAdding();Active = false;if (WatingTimeout == 0 || _task == null) return true;return _task.Wait(WatingTimeout);}public virtual bool AddMsg(object message){// 自动开始if (!Active){Start();}if (!Active){return false;}MailBox.Add(message);return true;}/// <summary>/// 循环消费消息/// </summary>private void DoActorWork(){while (!MailBox.IsCompleted){try{var ctx = MailBox.Take();var task = ProcessAsync(ctx);if (task != null){task.Wait();}}catch (InvalidOperationException) { }catch (Exception ex){Console.WriteLine($"DoActorWork Error : {ex.Message}");}}Active = false;}/// <summary>/// 处理消息/// </summary>/// <returns></returns>public abstract Task ProcessAsync(object msg);public void Dispose(){try{Stop(100);}catch (Exception){}while (MailBox?.TryTake(out _) == true) { }MailBox = null;}
}

相关测试模型

AccumulationActor.cs

/// <summary>
/// 累加
/// </summary>
public class AccumulationActor : Actor
{private int Count = 0;private IActor actor;public AccumulationActor(IActor actor) : base(nameof(AccumulationActor)){Count = 0;this.actor = actor;}   /// <summary>/// 处理信息/// </summary>/// <returns></returns>public override Task ProcessAsync(object msg){try{var  msgNumber = (int)(msg);Count += msgNumber;Console.WriteLine($"处理{this.Name} :{msg} ,累积总数:{Count}");if (Count >= 100){this.actor.AddMsg(Count);Count = 0;}}catch (Exception e){Console.WriteLine($"业务处理异常:{e.Message}");}return Task.CompletedTask;}
}

WriteActor.cs

/// <summary>/// 输出/// </summary>public class WriteActor : Actor{public WriteActor() : base(nameof(WriteActor)){}/// <summary>/// 处理信息/// </summary>/// <returns></returns>public override Task ProcessAsync(object msg){try{Console.WriteLine($"输出 {this.Name} :{msg}");}catch (Exception e){Console.WriteLine($"业务处理异常:{e.Message}");}return Task.CompletedTask;}}

测试代码

static void Main(string[] args)
{Console.Title = "Actor Demo by 蓝创精英团队";//实现一个加法逻辑//a累加到100,就发送消息到 b里,让b 输出。var write = new WriteActor();var User = new AccumulationActor(write);for (int i = 0; i < 20; i++){User.AddMsg(i * 30);}Thread.Sleep(2000);write.Stop();User.Stop();//释放资源Console.WriteLine("示例完毕!");Console.ReadLine();
}

运行结果

7a7288f3f55ed79ed96135a2269ad974.png

总结

上节实现了状态机,这节实现了Actor模型,接下来对Orleans 和 Dapr 的核心原理就了解深入一些了,那么,运用这些技术就不会显的很生涩。

代码地址

https://github.com/kesshei/ActorDemo.git

https://gitee.com/kesshei/ActorDemo.git

一键三连呦!,感谢大佬的支持,您的支持就是我的动力!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/285111.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

oracle--number

1. oracle的number类型是oracle的内置类型之一&#xff0c;是oracle的最基础数值数据类型。在9iR2及其以前的版本中只支持一种适合存储数值数据的固有数据类型&#xff0c;在10g以后&#xff0c;才出现了两种新的数值类型&#xff0c;即推出本地浮点数据类型(Native Floating-P…

超详细C语言版数据结构:图的深度优先遍历(推荐收藏)

文章目录一、邻接矩阵存储图的深度优先遍历过程分析二、结果分析三、C语言编程实现图的深度优先遍历四、图的遍历及其应用一、邻接矩阵存储图的深度优先遍历过程分析 对图1这样的无向图&#xff0c;要写成邻接矩阵&#xff0c;则就是下面的式子&#xff1a; 一般要计算这样的问…

Navicat Premium 64 bit 12.1.25

Navicat Premium可让你以单一程序同時连接到 MySQL、MariaDB、SQL Server、SQLite、Oracle 和 PostgreSQL 数据库&#xff0c;是一个可多重连接的数据库管理工具&#xff0c;它让管理不同类型的数据库更加方便。 官方下载地址&#xff1a;https://www.navicat.com.cn/download/…

C语言试题166之整数逆序输出

📃个人主页:个人主页 🔥系列专栏:C语言试题200例 💬推荐一款刷算法、笔试、面经、拿大公司offer神器👉 点击跳转进入网站 ✅作者简介:大家好,我是码莎拉蒂,CSDN博客专家(全站排名Top 50),阿里云博客专家、51CTO博客专家、华为云享专家 1、题目 题目:将一个从…

[JMX一步步来] 7、用JDK5.0的JConsole来连接MBean

前面所有看效果都是通过Html网页来看的。JDK5.0自带了一个jmx客户端&#xff0c;叫jconsole&#xff0c;位于c:\jdk\bin\jconsole.exe。我们来用用这个客户端来连接Mbean Server。一、vm参数方式1、还是用第一篇的那个HelloAgent&#xff0c;修改HelloAgent&#xff0c;将第一句…

记一次 .NET 某新能源系统 线程疯涨 分析

一&#xff1a;背景 1. 讲故事前段时间收到一个朋友的求助&#xff0c;说他的程序线程数疯涨&#xff0c;寻求如何解决。等我分析完之后&#xff0c;我觉得这个问题很有代表性&#xff0c;所以拿出来和大家分享下&#xff0c;还是上老工具 WinDbg。二&#xff1a;WinDbg 分析 1…

【原创】请避免GO语言中的携程空跑(CPU突然激增)

其实GO语言从1.6版本开始非常不错了&#xff0c;GC性能优化非常到位&#xff0c;并且各种并行设计比从新实现一套C版本的确是方便不少。 语言包也很多&#xff0c;库也相对稳定&#xff0c;完全可以适用于生产环境。 本文主要是给刚刚入门新手注意一个携程空跑的问题&#xff0…

在Linux上启动oracle 11g OEM

[rootfmw ~]# su - oracle[oraclefmw ~]$ emctl start dbconsole转载于:https://blog.51cto.com/weichanglong/1762783

[转]ES7、ES8、ES9、ES10新特性大盘点

ES7、ES8、ES9、ES10新特性大盘点 本文转自&#xff1a;https://mp.weixin.qq.com/s/8bov6788ivV0sHzmwrn5lw 以下文章来源于前端工匠 &#xff0c;作者浪里行舟君 前端工匠 我是浪里行舟&#xff0c;Github博客4000star作者&#xff0c;致力于打造一系列能够帮助初中级工程师…

热榜!!!数据结构与算法:C语言版---数组与稀疏矩阵---强势来袭!

数组是各种计算机语言中经常使用到的重要数据结构&#xff0c;一般的说&#xff1a;在内存中申请一片连续地址的存储空间、存储这些数、就称为数组。 在C语言中&#xff0c;申请连续的存储空间是很容易的事情&#xff0c;但难在多维数组的组织、以及数组数据的压缩上&#xff…

C语言试题167之字符串加密和解密算法

📃个人主页:个人主页 🔥系列专栏:C语言试题200例 💬推荐一款刷算法、笔试、面经、拿大公司offer神器👉 点击跳转进入网站 ✅作者简介:大家好,我是码莎拉蒂,CSDN博客专家(全站排名Top 50),阿里云博客专家、51CTO博客专家、华为云享专家 1、题目 题目:在本实例…

第一声问候

前一篇《Emacs 是一台计算机》理解了 Emacs 身为计算机的本质之后&#xff0c;在 Emacs 里编程就顺理成章了。不过&#xff0c;在此之前&#xff0c;还需要略微介绍一下 Emacs 最基本的操作。 系统的不一致&#xff0c;令人有点烦躁 现在&#xff0c;也可以坦然地说&#xff0c…

破解支付宝AR红包

支付宝新出的AR红包没多久&#xff0c;就有人破解了&#xff0c;大致原理是将上面的像素条遮挡下面的黑条&#xff0c;基本上得到模糊的图就可以扫到红包。不过现在大多是ps解决&#xff0c;那得有多麻烦啊&#xff0c;所以我用java写了一个&#xff0c;效果还不错。 先截屏&am…

在 Windows 上搭建配置 Jenkins 然后编译打包 VS 项目

在 Windows 上搭建配置 Jenkins 然后编译打包 VS 项目独立观察员 2022 年 7 月 6 日一、安装1、下载并安装 JRE &#xff08;Java 运行环境&#xff09;。2、下载 Windows 版本的 Jenkins 安装包并安装。3、安装 Visual Studio&#xff0c;以供编译项目使用。4、安装 Advanced …

【ArcGIS微课1000例】0007:基于数字高程模型DEM生成剖面线、剖面图

文章目录 效果预览数据分析工具介绍生成过程剖面图编辑保存、导出剖面图实验数据下载效果预览 数据分析 本实例使用到的原始数据为案例提供的规则格网DEM

[转]javaandroid线程池

java多线程-概念&创建启动&中断&守护线程&优先级&线程状态&#xff08;多线程编程之一&#xff09;java多线程同步以及线程间通信详解&消费者生产者模式&死锁&Thread.join()&#xff08;多线程编程之二&#xff09;java&android线程池-Exe…

C#实现清理系统内存

金山内存整理工具、360内存清理工具非常好用&#xff0c;可以将系统内存最小化&#xff0c;提升系统运行速度。其实这些事情C#也可以做到&#xff0c;原理就是对系统进程中的进程内存进行逐个优化。 网上大多推荐使用系统的SetProcessWorkingSetSize的函数API&#xff0c;但是经…

C语言试题168之获取矩阵的最大值及其下标

📃个人主页:个人主页 🔥系列专栏:C语言试题200例 💬推荐一款刷算法、笔试、面经、拿大公司offer神器👉 点击跳转进入网站 ✅作者简介:大家好,我是码莎拉蒂,CSDN博客专家(全站排名Top 50),阿里云博客专家、51CTO博客专家、华为云享专家 1、题目 题目:要求使用…

.Net下极限生产力之efcore分表分库全自动化迁移CodeFirst

开始本次我们的主题就是极限生产力,其他语言望尘莫及的分表分库全自动化Migrations Code-First 加 efcore 分表分库无感开发还记得上次发布博客还是在上次,上次发布了如何兼容WTM框架后也有不少小伙伴来问我如何兼容如何迁移等问题,经过这么多框架的兼容我自己也认识到了一些问…

Hadoop日常管理与维护

本文描述了hadoop、hbase的启动关闭、表操作以及权限管理。一、Hadoop服务的启动与关闭1、启动使用hadoop以及hbase自带的脚本进行启动&#xff0c;先启动hadoop个服务&#xff0c;再启动hbase服务。 hadoopbdi:~$ start-dfs.sh hadoopbdi:~$ start-yarn.sh hadoopbdi:~$ start…