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.pswp.cn/news/285111.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/285111.shtml
英文地址,請注明出處:http://en.pswp.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…