根据老赵轻量级Actor进行修改的Actor模型
学习了老赵轻量级Actor模型,并在实际中使用,效果不错。
老赵轻量级Actor模型:
ActorLite:一个轻量级Actor模型实现(上)
ActorLite:一个轻量级Actor模型实现(中)
ActorLite:一个轻量级Actor模型实现(下)
但是在使用此模式的过程中,在message出队列时出现问题,出现queue.count == 0的异常,没能分析出问题的原因,暂时做了一个临时性的解决方案,也并没有测试对性能的影响。
1 /// <summary> 2 /// Actor模型接口 3 /// </summary> 4 internal interface IActor 5 { 6 /// <summary> 7 /// 执行 8 /// </summary> 9 void Execute(); 10 /// <summary> 11 /// 退出标志 12 /// </summary> 13 bool Exited { get; } 14 /// <summary> 15 /// 消息个数 16 /// </summary> 17 int MessageCount { get; } 18 /// <summary> 19 /// Actor上下文 20 /// </summary> 21 ActorContext Context { get; } 22 } 23 24 /// <summary> 25 /// Actor上下文类 26 /// </summary> 27 internal class ActorContext 28 { 29 // 表示某一时期处理消息的状态 30 public int Status; 31 32 /// <summary> 33 /// 保存Actor模型类的引用 34 /// </summary> 35 public IActor Actor { get; private set; } 36 37 /// <summary> 38 /// 构造函数 39 /// </summary> 40 /// <param name="actor"></param> 41 public ActorContext(IActor actor) 42 { 43 this.Actor = actor; 44 } 45 46 // Actor模型执行状态,包括 等待、执行和退出三个状态 47 public const int Waiting = 0; 48 public const int Executing = 1; 49 public const int Exited = 2; 50 } 51 52 /// <summary> 53 /// Actor模型类 54 /// </summary> 55 /// <typeparam name="T"></typeparam> 56 public abstract class Actor<T> : IActor 57 { 58 // Actor上下文对象 59 private readonly ActorContext _context; 60 61 // Exit flag 62 private bool _exited = false; 63 64 // Message queue 65 private readonly ConcurrentQueue<T> _messageQueue = new ConcurrentQueue<T>(); 66 67 /// <summary> 68 /// 投递消息 69 /// </summary> 70 /// <param name="message"></param> 71 public void Post(T message) 72 { 73 if (this._exited) 74 { 75 return; 76 } 77 this._messageQueue.Enqueue(message); 78 // 准备执行处理一个消息 79 Dispatcher.Instance.ReadyToExecute(this); 80 } 81 82 // 接收并处理消息 83 protected abstract void Receive(T message); 84 85 /// <summary> 86 /// Constructor 87 /// </summary> 88 protected Actor() 89 { 90 this._context = new ActorContext(this); 91 } 92 93 #region Properties 94 /// <summary> 95 /// Actor上下文 96 /// </summary> 97 ActorContext IActor.Context 98 { 99 get { return this._context; } 100 } 101 /// <summary> 102 /// 是否退出标志 103 /// </summary> 104 bool IActor.Exited 105 { 106 get { return this._exited; } 107 } 108 /// <summary> 109 /// 消息队列中消息个数 110 /// </summary> 111 int IActor.MessageCount 112 { 113 get { return this._messageQueue.Count; } 114 } 115 #endregion 116 117 /// <summary> 118 /// 处理消息 119 /// </summary> 120 void IActor.Execute() 121 { 122 T message; 123 var dequeueSucess = this._messageQueue.TryDequeue(out message); 124 125 if (dequeueSucess) 126 { 127 this.Receive(message); 128 } 129 } 130 131 protected void Start() 132 { 133 this._exited = false; 134 } 135 /// <summary> 136 /// 退出模式 137 /// </summary> 138 protected void Exit() 139 { 140 this._exited = true; 141 } 142 } 143 144 /// <summary> 145 /// 分发类 146 /// </summary> 147 internal class Dispatcher 148 { 149 // Singleton 150 private static readonly Dispatcher _instance = new Dispatcher(); 151 152 public static Dispatcher Instance 153 { 154 get { return _instance; } 155 } 156 157 /// <summary> 158 /// Private Constructor 159 /// </summary> 160 private Dispatcher() 161 { 162 163 } 164 165 /// <summary> 166 /// 消息预处理:设置处理状态 167 /// </summary> 168 /// <param name="actor"></param> 169 public void ReadyToExecute(IActor actor) 170 { 171 if (actor.Exited) return; 172 // 修改当前状态为执行态 173 int status = Interlocked.CompareExchange(ref actor.Context.Status, ActorContext.Executing, ActorContext.Waiting); 174 175 if (status == ActorContext.Waiting) 176 { 177 // 线程池的可用工作线程处理消息 178 ThreadPool.QueueUserWorkItem(this.Execute, actor); 179 } 180 } 181 182 /// <summary> 183 /// 消息处理 184 /// </summary> 185 /// <param name="o"></param> 186 private void Execute(object o) 187 { 188 IActor actor = (IActor)o; 189 // 190 actor.Execute(); 191 // 如果退出,则设置退出标志位 192 if (actor.Exited) 193 { 194 Thread.VolatileWrite(ref actor.Context.Status, ActorContext.Exited); 195 } 196 // 否则进行下一个消息处理 197 else 198 { 199 Thread.VolatileWrite(ref actor.Context.Status, ActorContext.Waiting); 200 if (actor.MessageCount > 0) 201 { 202 this.ReadyToExecute(actor); 203 } 204 } 205 } 206 }
修改的位置:
1 /// <summary> 2 /// 处理消息 3 /// </summary> 4 void IActor.Execute() 5 { 6 T message; 7 var dequeueSucess = this._messageQueue.TryDequeue(out message); 8 9 if (dequeueSucess) 10 { 11 this.Receive(message); 12 } 13 }
老赵原来的方式:
1 public void Post(T message) 2 { 3 if (this.m_exited) return; 4 5 lock (this.m_messageQueue) 6 { 7 this.m_messageQueue.Enqueue(message); 8 } 9 10 Dispatcher.Instance.ReadyToExecute(this); 11 }
转载于:https://www.cnblogs.com/dingzhouta/p/5262744.html
根据老赵轻量级Actor进行修改的Actor模型相关推荐
- 对老赵写的简单性能计数器的修改
对老赵写的简单性能计数器的修改 早上看到老赵写的这个性能计数器,感觉很实用,不过老赵用了很多.C# 3.0 的新语法,还用了 VISTA 和 Server 2008 下特有的Win32 API,对于还 ...
- 【转载】Erlang精彩讨论-回“老赵”关于“Erlang中最大的问题”
原文:http://erlang-china.org/study/puzzle-in-erlang_pattern_match.html/comment-page-1#comments http:// ...
- 老赵谈IL(3):IL可以看到的东西,其实大都也可以用C#来发现
在上一篇文章中,我们通过一些示例谈论了IL与CLR中的一些特性.IL与C#等高级语言的作用类似,主要用于表示程序的逻辑.由于它同样了解太多CLR中的高级特性,因此它在大部分情况下依旧无法展现出比那些高 ...
- 艾伟:老赵谈IL(3):IL可以看到的东西,其实大都也可以用C#来发现
在上一篇文章中,我们通过一些示例谈论了IL与CLR中的一些特性.IL与C#等高级语言的作用类似,主要用于表示程序的逻辑.由于它同样了解太多CLR中的高级特性,因此它在大部分情况下依旧无法展现出比那些高 ...
- 老赵谈IL(4):什么时候应该学IL,该怎么学IL
又是一个拖了半年的系列,可能是前几篇主要以事实为准,举例子的文章总是比较容易写的,因此十分顺畅.而最后一篇打算做一个总结,以讲道理为主--却发现该将的似乎都已经讲完了.不过做事要有始有终,该完成的也必 ...
- 老赵的自然数分解——少侠之对象解
自然数分解算法的起因介绍,老赵 前几天贴了个非递归的 今天继续搞一个使用对象的解 坚持用对象来解决问题的一个原因,是想证明使用面向对象不是造成算法速度慢的根本原因 例如,我这个面向对象的解,其运行速度 ...
- 解读网络“攻城狮”的发展---老赵带你铺一段路
成为网络工程师要学什么.如何学.在哪儿学,网络工程师的发展如何.薪资待遇如何等问题困扰着很多网络技术人员,尤其是正在学校苦苦寻求真理的同学们.我也是一名在校大学生,深知现在同学们的苦恼.如果能掌握关于 ...
- 用dotTace模仿下老赵的“使用Profiler分析程序性能”
最近看到老赵博客"使用Profiler分析程序性能"(http://www.cnblogs.com/JeffreyZhao/archive/2009/12/22/profiler- ...
- 老赵被刷票了,但这不是老赵做的
[url]http://www.51cto.com/exp/hhhchina/heroes/index.html[/url] 老赵今天早上大约9点开始被人刷票,当时票数为8700多,但是不久后就发现票 ...
最新文章
- Shell脚本读取命令行参数
- .net网格怎么把值插入指定列表_Python列表有什么内置函数可以使用,怎么使用这些函数...
- windows使用ssh2远程登陆ubuntu
- Cannot SET AUTOTRACE 处理办法
- mysql简单语句_MySQL 简单的语句
- 关闭vue中的eslint校验
- 电力物联网智慧路灯充电桩传感器技术应用方案
- 如何将div与页面的中间(水平/宽度)对齐[重复]
- JVM 堆内存设置 -Xmx -Xms
- VMware12序列号
- linux安装酷q机器人,docker一键安装酷Q搭建个人QQ机器人
- 20201125 plecs更新
- PuTTY/PuttyGen创建密钥及利用密钥登录服务器
- 阿里云Oss云存储的使用步骤
- 如何将Word转PDF?来看这几个方法
- android设置自动亮度,android5.1 自动亮度调节简析
- 原码,反码,补码的深入理解与原理
- 数据分析学习(一)数据分析和Numpy基础
- 同事逆袭面进阿里P7 年薪60W+,临别留下一张Android开发重点技术路线图
- john the ripper 使用