异步指令的执行机制
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 }
定制开发行业软件
posted on 2018-08-31 15:33 youmeetmehere 阅读(511) 评论(0) 编辑 收藏 举报