学习了老赵轻量级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模型相关推荐

  1. 对老赵写的简单性能计数器的修改

    对老赵写的简单性能计数器的修改 早上看到老赵写的这个性能计数器,感觉很实用,不过老赵用了很多.C# 3.0 的新语法,还用了 VISTA 和 Server 2008 下特有的Win32 API,对于还 ...

  2. 【转载】Erlang精彩讨论-回“老赵”关于“Erlang中最大的问题”

    原文:http://erlang-china.org/study/puzzle-in-erlang_pattern_match.html/comment-page-1#comments http:// ...

  3. 老赵谈IL(3):IL可以看到的东西,其实大都也可以用C#来发现

    在上一篇文章中,我们通过一些示例谈论了IL与CLR中的一些特性.IL与C#等高级语言的作用类似,主要用于表示程序的逻辑.由于它同样了解太多CLR中的高级特性,因此它在大部分情况下依旧无法展现出比那些高 ...

  4. 艾伟:老赵谈IL(3):IL可以看到的东西,其实大都也可以用C#来发现

    在上一篇文章中,我们通过一些示例谈论了IL与CLR中的一些特性.IL与C#等高级语言的作用类似,主要用于表示程序的逻辑.由于它同样了解太多CLR中的高级特性,因此它在大部分情况下依旧无法展现出比那些高 ...

  5. 老赵谈IL(4):什么时候应该学IL,该怎么学IL

    又是一个拖了半年的系列,可能是前几篇主要以事实为准,举例子的文章总是比较容易写的,因此十分顺畅.而最后一篇打算做一个总结,以讲道理为主--却发现该将的似乎都已经讲完了.不过做事要有始有终,该完成的也必 ...

  6. 老赵的自然数分解——少侠之对象解

    自然数分解算法的起因介绍,老赵 前几天贴了个非递归的 今天继续搞一个使用对象的解 坚持用对象来解决问题的一个原因,是想证明使用面向对象不是造成算法速度慢的根本原因 例如,我这个面向对象的解,其运行速度 ...

  7. 解读网络“攻城狮”的发展---老赵带你铺一段路

    成为网络工程师要学什么.如何学.在哪儿学,网络工程师的发展如何.薪资待遇如何等问题困扰着很多网络技术人员,尤其是正在学校苦苦寻求真理的同学们.我也是一名在校大学生,深知现在同学们的苦恼.如果能掌握关于 ...

  8. 用dotTace模仿下老赵的“使用Profiler分析程序性能”

    最近看到老赵博客"使用Profiler分析程序性能"(http://www.cnblogs.com/JeffreyZhao/archive/2009/12/22/profiler- ...

  9. 老赵被刷票了,但这不是老赵做的

    [url]http://www.51cto.com/exp/hhhchina/heroes/index.html[/url] 老赵今天早上大约9点开始被人刷票,当时票数为8700多,但是不久后就发现票 ...

最新文章

  1. Shell脚本读取命令行参数
  2. .net网格怎么把值插入指定列表_Python列表有什么内置函数可以使用,怎么使用这些函数...
  3. windows使用ssh2远程登陆ubuntu
  4. Cannot SET AUTOTRACE 处理办法
  5. mysql简单语句_MySQL 简单的语句
  6. 关闭vue中的eslint校验
  7. 电力物联网智慧路灯充电桩传感器技术应用方案
  8. 如何将div与页面的中间(水平/宽度)对齐[重复]
  9. JVM 堆内存设置 -Xmx -Xms
  10. VMware12序列号
  11. linux安装酷q机器人,docker一键安装酷Q搭建个人QQ机器人
  12. 20201125 plecs更新
  13. PuTTY/PuttyGen创建密钥及利用密钥登录服务器
  14. 阿里云Oss云存储的使用步骤
  15. 如何将Word转PDF?来看这几个方法
  16. android设置自动亮度,android5.1 自动亮度调节简析
  17. 原码,反码,补码的深入理解与原理
  18. 数据分析学习(一)数据分析和Numpy基础
  19. 同事逆袭面进阿里P7 年薪60W+,临别留下一张Android开发重点技术路线图
  20. john the ripper 使用

热门文章

  1. 戴尔t630服务器系统,远比你想象的强大 塔式服务器也玩GPU
  2. 怎么查找适合发表的国际会议?
  3. faiss python安装_faiss安装及使用
  4. linux支持三种类型的硬件,linux
  5. Xshell常用命令大全(附常用实例)
  6. #如何创新玩转HarmonyOS开发#厚积薄发
  7. 带关闭按钮的滚动广告
  8. 0xC004F069错误的解决方案
  9. 如何在Linux系统下安装英特尔® Arc™系列独立显卡驱动以及进行AI推理性能测试...
  10. MacBook 电池电量未达到 100%?如何关闭电池健康管理