根据老赵轻量级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     }

 

posted on 2016-03-10 17:31  定州塔  阅读(416)  评论(0)    收藏  举报

导航