首页 > 技术文章 > 异步指令的执行机制

youmeetmehere 2018-08-31 15:33 原文

  1 //------------------------------------------摘要------------------------------------------
  2 // 产品名称:动作队列
  3 // 文 件 名:ActionsQueue
  4 // 文件说明:
  5 // 机器名称:EIBJDE0153
  6 // 作  者:zhengping.pan
  7 // 创建日期:2017-12-19 11:31:09
  8 //----------------------------------------------------------------------------------------
  9 using System;
 10 using System.Collections.Generic;
 11 using System.Linq;
 12 using System.Text;
 13 using System.Threading;
 14 
 15 namespace EURO.DeviceManager.MultiNeedlesArm.DataModel
 16 {
 17     /// <summary>
 18     /// 动作队列
 19     /// </summary>
 20     internal class ActionsQueue : Queue<ActionInvoke>
 21     {
 22 
 23         #region 字段
 24         /// <summary>
 25         /// 队列名称
 26         /// </summary>
 27         public string Name { get; set; }
 28 
 29         ///// <summary>
 30         ///// 执行的当前队列中的动作。用于在执行下一个时,取上一个的动作。
 31         ///// </summary>
 32         private ActionInvoke _currentAction = null;
 33 
 34         /// <summary>
 35         /// 执行的当前方法名称
 36         /// </summary>
 37         private string _currentFunctionName;
 38 
 39         /// <summary>
 40         /// 控制列表访问的锁
 41         /// </summary>
 42         private object _queueLock = new object();
 43 
 44         /// <summary>
 45         /// 是否请求停止
 46         /// </summary>
 47         //private bool _IsQueryStop = false;
 48 
 49         private Thread _actionsThread = null;
 50 
 51         /// <summary>
 52         /// 阻塞或继续动作线程
 53         /// </summary>
 54         private AutoResetEvent _ar_Excute = new AutoResetEvent(false);
 55         #endregion
 56 
 57         #region 构造
 58         public ActionsQueue()
 59         {
 60             StartActionsThread();
 61         }
 62         #endregion
 63 
 64         #region 公有方法
 65 
 66         /// <summary>
 67         /// 线程继续
 68         /// </summary>
 69         public void Set()
 70         {
 71             this._ar_Excute.Set();
 72         }
 73 
 74         /// <summary>
 75         /// 开始动作线程
 76         /// </summary>
 77         private void StartActionsThread()
 78         {
 79             _actionsThread = new Thread(new ThreadStart(Excute)) { IsBackground = true, Priority = ThreadPriority.Normal };
 80             _actionsThread.Start();
 81         }
 82 
 83         /// <summary>
 84         /// 释放
 85         /// </summary>
 86         public void Release()
 87         {
 88             this.Clear();
 89             if (_actionsThread != null)
 90             {
 91                 _actionsThread.Abort();
 92             }
 93             this.Clear();
 94         }
 95 
 96         #endregion
 97 
 98         #region 私有方法
 99 
100 
101         /// <summary>
102         /// 执行队列循环
103         /// </summary>
104 
105         private void Excute()
106         {
107             while (true)
108             {
109                DoDequeue();
110             }
111         }
112 
113         /// <summary>
114         /// 执行队列中一个方法
115         /// </summary>
116         private void DoDequeue()
117         {
118             if (this.Count == 0)
119             {
120                 _currentAction = null;
121                 _ar_Excute.WaitOne();
122             }
123             if (this.Count > 0)
124             {
125                     ActionInvoke func = this.Dequeue();
126                     if (null == func)
127                     {
128                         ErrorEventManager.Manager.SetInforStr(string.Format("{0} .Dequeue is NULL !", this.Name));
129                         return;
130                     }
131                     // 上条指令的延时
132                     if (_currentAction != null && _currentAction.NextDelayTime > 0)
133                     {
134                         Thread.Sleep(_currentAction.NextDelayTime);
135                     }
136 
137                     // 如果是不需要判断ACK的方法,直接执行.
138                     if (func.Action.Method.Name.ToLower().Contains("finishedmethod") || !func.IsNeedAck || func.SMID <= 0)
139                     {
140                         _currentFunctionName = func.TaskName;
141                         try
142                         {
143                             func.Action.Method.Invoke(func.Action.Target, func.Parameters);
144                         }
145                         catch(Exception ex)
146                         {
147                             string strDescribe = ex.ToString();
148                             ErrorEventManager.Manager.SetInformation(new ErrorEventArgs(ErrorRank.Error, DeviceErrorCode.InvokeError, strDescribe));
149                             throw new ErrorException(DeviceErrorCode.InvokeError, strDescribe);
150                             //break;
151                         }
152                         _currentAction = func;
153                     }
154                     else
155                     {
156                         //==================================================================
157                         while (!ACKAndFinishManager.ACKManager.IsAllAccept())
158                         {
159                             Thread.Sleep(10);
160                         }
161                         while (!ACKAndFinishManager.FinishManager.IsThisIDAccept(func.SMID))
162                         {
163                             Thread.Sleep(10);
164                         }
165                         #region Finish锁
166                         lock (ACKAndFinishManager.FinishLockDic[func.SMID])
167                         {
168                             #region ACK锁
169                             lock (ACKAndFinishManager.AckLockObj)
170                             {
171                                 if (func.IsNeedAck)
172                                 {
173                                     ACKAndFinishManager.ACKManager.SetState(func.SMID, false);
174                                     ACKAndFinishManager.FinishManager.SetState(func.SMID, false);
175                                 }
176                                 else
177                                 {
178 
179                                 }
180                                 func.IsFinished.Value = false;
181                                 try
182                                 {
183                                     func.Action.Method.Invoke(func.Action.Target, func.Parameters);
184                                 }
185                                 catch(Exception ex)
186                                 {
187                                     string strDescribe = ex.ToString();
188                                     ErrorEventManager.Manager.SetInformation(new ErrorEventArgs(ErrorRank.Error, DeviceErrorCode.InvokeError, strDescribe));
189                                     throw new ErrorException(DeviceErrorCode.InvokeError, strDescribe);
190                                     //break;
191                                 }
192                                 _currentAction = func;
193 
194                                 // 等待ACK
195                                 int ackCount = 0;
196                                 int sendCount = 0;
197                                 // 如果需要等待ACK
198                                 while (!ACKAndFinishManager.ACKManager.IsThisIDAccept(func.SMID) && func.IsNeedAck)
199                                 {
200                                     Thread.Sleep(25);
201                                     ackCount++;
202                                     // 200ms没收到ACK超时
203                                     if (sendCount >= 4 && ackCount >= 10)
204                                     {
205                                         string strDescribe = string.Format("{0} .{1} !", func.Action.Method.ToString(), ErrorCodeHelper.GetErrorInfo((int)DeviceErrorCode.NoAck));
206                                         ErrorEventManager.Manager.SetInformation(new ErrorEventArgs(ErrorRank.Error, DeviceErrorCode.NoAck, strDescribe));
207                                         throw new ErrorException(DeviceErrorCode.NoAck, strDescribe);
208                                     }
209                                     if (ackCount == 10)
210                                     {
211                                         if (sendCount == 2)
212                                         {
213                                             try
214                                             {
215                                                 func.Action.Method.Invoke(func.Action.Target, func.Parameters);
216                                             }
217                                             catch (Exception ex)
218                                             {
219                                                 string strDescribe = ex.ToString();
220                                                 ErrorEventManager.Manager.SetInformation(new ErrorEventArgs(ErrorRank.Error, DeviceErrorCode.InvokeError, strDescribe));
221                                                 throw new ErrorException(DeviceErrorCode.InvokeError, strDescribe);
222                                                 //break;
223                                             }
224                                         }
225                                         sendCount++;
226                                         ackCount = 0;
227                                     }
228                                 }
229                             }
230                             #endregion
231                             //======================================================
232                             // Finished事件
233                             DateTime dtStart = DateTime.Now;
234                             while (!ACKAndFinishManager.FinishManager.IsThisIDAccept(func.SMID))
235                             {
236                                 Thread.Sleep(20);
237                                 TimeSpan ts = DateTime.Now - dtStart;
238                                 if (ts.TotalSeconds > 20)
239                                 {
240                                     if (func.IsNeedAck)
241                                     {
242                                         string strDescribe = string.Format("{0} .{1} !", func.Action.Method.ToString(), ErrorCodeHelper.GetErrorInfo((int)DeviceErrorCode.NoFinish));
243                                         ErrorEventManager.Manager.SetInformation(new ErrorEventArgs(ErrorRank.Error, DeviceErrorCode.NoFinish, strDescribe));
244                                         throw new ErrorException(DeviceErrorCode.NoFinish, strDescribe);
245                                         //break;
246                                     }
247                                 }
248                             }
249                             Thread.Sleep(20);
250                         }
251                         #endregion  //// Finish锁结束
252                     }
253 
254             }
255 
256         }
257 
258         #endregion
259 
260     }
261 }

 

推荐阅读