RoutineRunner.cs 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Diagnostics;
  5. using Aitex.Core.RT.Log;
  6. using MECF.Framework.Common.Equipment;
  7. using CyberX8_Core;
  8. using Aitex.Core.RT.Routine;
  9. using System.Threading;
  10. namespace MECF.Framework.Common.Routine
  11. {
  12. public class RoutineRunner
  13. {
  14. public RState Status => _runnerState;
  15. private bool IsSubStepRunning(Enum id) => _runnerState == RState.Running && _subState == RState.Running && (_curStep != null && _curStep.GetHashCode() == id.GetHashCode());
  16. private bool bAllowSubStepStart(Enum id) => _runnerState == RState.Running && _subState == RState.End && !_steps.Contains(id) && _isLoopMode == false;
  17. private bool bAllowLoopSubStepStart(Enum id) => _runnerState == RState.Running && _subState == RState.End && !_steps.Contains(id) && _isLoopMode;
  18. public int LoopCounter => _loopCounter;
  19. public long StepElapsedMS => _subStepTimer.ElapsedMilliseconds;
  20. private RState _subState = RState.Init;
  21. private Stack<Enum> _steps = new Stack<Enum>();
  22. private Stack<Enum> _loopSteps = new Stack<Enum>();
  23. enum InvalidStep { Invalid = 0x7FFFFFFF, };
  24. public Enum CurrentStep => _curStep;
  25. private Enum _curStep = InvalidStep.Invalid;
  26. private RState _runnerState = RState.Init;
  27. private string _name;
  28. private string _loopName;
  29. private string _module;
  30. // 缺省最大超时 10 分钟, delay 5 秒
  31. private const int _defaultTimeout = 600000;
  32. private const int _defaultDelay = 200;
  33. private const int _defaultDelay_5s = 5000;
  34. //用于计时
  35. Stopwatch _subStepTimer = new Stopwatch();
  36. private bool _isLoopMode = false;
  37. private int _loopCounterSP = 0;
  38. private int _loopCounter = 0;
  39. private int _subRoutineIndex = -1;
  40. private IRoutine _subRoutine = null;
  41. static private int _RunnerToken = 0;
  42. private Stopwatch _stopwatch = new Stopwatch();
  43. private string _errorMsg = "";
  44. public string ErrorMsg { get{ return _errorMsg; } set { _errorMsg = value; } }
  45. /// <summary>
  46. /// 完成时长
  47. /// </summary>
  48. public long ElapsedMS =>_stopwatch.ElapsedMilliseconds;
  49. public RoutineRunner()
  50. {
  51. _runnerState = RState.Init;
  52. }
  53. public void Reset()
  54. {
  55. _runnerState = RState.Init;
  56. _subState = RState.Init;
  57. _isLoopMode = false;
  58. _steps.Clear();
  59. _loopSteps.Clear();
  60. _stopwatch.Reset();
  61. _subStepTimer.Reset();
  62. _errorMsg = "";
  63. }
  64. public RState Start(ModuleName module, string name)
  65. {
  66. Reset();
  67. _module = module.ToString();
  68. _name = $"{name} (Token:{_RunnerToken++})";
  69. _runnerState = RState.Running;
  70. _subState = RState.End;
  71. _stopwatch.Restart();
  72. Notify("开始");
  73. return _runnerState;
  74. }
  75. public RState Start(string module, string name)
  76. {
  77. Reset();
  78. _module = module;
  79. _name = $"{name} (Token:{_RunnerToken++})";
  80. _runnerState = RState.Running;
  81. _subState = RState.End;
  82. _stopwatch.Restart();
  83. Notify("开始");
  84. return _runnerState;
  85. }
  86. /// <summary>
  87. /// 重试
  88. /// </summary>
  89. /// <param name="id"></param>
  90. /// <returns></returns>
  91. public RState Retry(Enum id,List<Enum> _preStepIds,string module, string name)
  92. {
  93. Reset();
  94. foreach (Enum item in _preStepIds)
  95. {
  96. _steps.Push(item);
  97. }
  98. _module = module;
  99. _name = $"{name} (Token:{_RunnerToken++})";
  100. _runnerState = RState.Running;
  101. _subState = RState.End;
  102. _stopwatch.Restart();
  103. Notify($"{id} Retry");
  104. _curStep = id;
  105. return _runnerState;
  106. }
  107. public void Stop(string reason,bool error=false)
  108. {
  109. if (Status == RState.Running)
  110. {
  111. Alarm(reason, error);
  112. }
  113. _runnerState = _subState = RState.Failed;
  114. _stopwatch.Stop();
  115. }
  116. public RoutineRunner Run(Enum id, Func<bool> action, Func<bool> condition, int timeout = _defaultTimeout,bool error=true)
  117. {
  118. if (bAllowSubStepStart(id))
  119. {
  120. startNewStep(id, action,error);
  121. }
  122. else if(IsSubStepRunning(id))
  123. {
  124. if (condition())
  125. {
  126. _subState = RState.End;
  127. }
  128. else if(_subStepTimer.ElapsedMilliseconds >= timeout)
  129. {
  130. Alarm($"Step:{id} 超时",error);
  131. _runnerState = _subState = RState.Timeout;
  132. _subStepTimer.Reset();
  133. }
  134. }
  135. return this;
  136. }
  137. public RoutineRunner RunConditionSubRoutine(Enum id,Func<int> routeIndexAction, IRoutine[] routines, object[] objects)
  138. {
  139. if (bAllowSubStepStart(id))
  140. {
  141. StartNewStepConditionRoutine(id, routeIndexAction, routines, objects);
  142. }
  143. else if(IsSubStepRunning(id))
  144. {
  145. if(_subRoutine==null)
  146. {
  147. _subState = RState.End;
  148. }
  149. else
  150. {
  151. if (objects.Length > _subRoutineIndex && _subRoutineIndex != -1)
  152. {
  153. _subRoutine.Start(objects[_subRoutineIndex]);
  154. }
  155. else
  156. {
  157. _subRoutine.Start();
  158. }
  159. _subState = RState.End;
  160. }
  161. }
  162. return this;
  163. }
  164. public RoutineRunner WaitConditionSubRoutine(Enum id)
  165. {
  166. if(bAllowSubStepStart(id))
  167. {
  168. Notify($"Step: {id} start ---");
  169. _steps.Push(id);
  170. _curStep = id;
  171. _subState = RState.Running;
  172. _subStepTimer.Restart();
  173. }
  174. else if(IsSubStepRunning(id))
  175. {
  176. if(_subRoutine==null)
  177. {
  178. _subState= RState.End;
  179. _subRoutineIndex = -1;
  180. }
  181. else
  182. {
  183. _subState = _subRoutine.Monitor();
  184. if(_subState==RState.End||_subState==RState.Failed||_subState==RState.Timeout)
  185. {
  186. _subRoutine = null;
  187. _subRoutineIndex = -1;
  188. }
  189. }
  190. }
  191. return this;
  192. }
  193. public void StartNewStepConditionRoutine(Enum id,Func<int> routeIndexAction, IRoutine[] routines, object[] objects)
  194. {
  195. _subRoutineIndex = routeIndexAction();
  196. if (routines.Length>_subRoutineIndex&&_subRoutineIndex!=-1)
  197. {
  198. _subRoutine = routines[_subRoutineIndex];
  199. }
  200. else
  201. {
  202. _subRoutine = null;
  203. }
  204. Notify($"Step: {id} start ---");
  205. _steps.Push(id);
  206. _curStep = id;
  207. _subState = RState.Running;
  208. _subStepTimer.Restart();
  209. }
  210. public RoutineRunner Run(Enum id, Func<bool> action, Func<bool> condition,Func<bool> failedCondition, int timeout = _defaultTimeout,bool error=true)
  211. {
  212. if (bAllowSubStepStart(id))
  213. {
  214. startNewStep(id, action);
  215. }
  216. else if (IsSubStepRunning(id))
  217. {
  218. if (condition())
  219. {
  220. _subState = RState.End;
  221. }
  222. else if(failedCondition())
  223. {
  224. _runnerState= _subState = RState.Failed;
  225. }
  226. else
  227. {
  228. if (_subStepTimer.ElapsedMilliseconds >= timeout)
  229. {
  230. Alarm($"Step:{id} 超时", error);
  231. _runnerState = _subState = RState.Timeout;
  232. _subStepTimer.Reset();
  233. }
  234. }
  235. }
  236. return this;
  237. }
  238. public RoutineRunner RunIf(Enum id, bool bRun, Func<bool> action, Func<bool> condition, int timeout = _defaultTimeout)
  239. {
  240. if(bRun)
  241. {
  242. return Run(id, action, condition, timeout);
  243. }
  244. return this;
  245. }
  246. public RoutineRunner RunIf(Enum id, bool bRun, Func<bool> action, Func<bool> condition, Func<bool> failedCondition, int timeout = _defaultTimeout)
  247. {
  248. if (bRun)
  249. {
  250. return Run(id, action, condition, failedCondition,timeout);
  251. }
  252. return this;
  253. }
  254. public RoutineRunner Run(Enum id, Func<bool> action, int delayMS = _defaultDelay)
  255. {
  256. if (bAllowSubStepStart(id))
  257. {
  258. startNewStep(id, action);
  259. }
  260. else if (IsSubStepRunning(id))
  261. {
  262. if (_subStepTimer.ElapsedMilliseconds > delayMS)
  263. {
  264. _subState = RState.End;
  265. }
  266. }
  267. return this;
  268. }
  269. public RoutineRunner RunDelay(Enum id, Func<bool> action, int delayMS = _defaultDelay)
  270. {
  271. if (bAllowSubStepStart(id))
  272. {
  273. startNewStep(id, () => { return true; });
  274. }
  275. else if (IsSubStepRunning(id))
  276. {
  277. if (_subStepTimer.ElapsedMilliseconds > delayMS)
  278. {
  279. if (!action())
  280. {
  281. Alarm($"Step: {id} Failed ");
  282. _runnerState = _subState = RState.Failed;
  283. _subStepTimer.Reset();
  284. }
  285. else
  286. {
  287. _subState = RState.End;
  288. }
  289. }
  290. }
  291. return this;
  292. }
  293. public RoutineRunner RunIf(Enum id, bool bRun, Func<bool> action, int delayMS = _defaultDelay)
  294. {
  295. if(bRun)
  296. {
  297. return Run(id, action, delayMS);
  298. }
  299. return this;
  300. }
  301. public RoutineRunner End(Enum id, Func<bool> action, Func<bool> condition, int timeout = _defaultTimeout)
  302. {
  303. if (bAllowSubStepStart(id))
  304. {
  305. startNewStep(id, action);
  306. }
  307. else if (IsSubStepRunning(id))
  308. {
  309. if (condition())
  310. {
  311. Notify($"结束");
  312. _runnerState = RState.End;
  313. _subState = RState.End;
  314. }
  315. else
  316. {
  317. if (_subStepTimer.ElapsedMilliseconds > timeout)
  318. {
  319. Alarm($"Step:{id} 超时");
  320. _runnerState = RState.Failed;
  321. _subState = RState.Timeout;
  322. }
  323. }
  324. }
  325. return this;
  326. }
  327. public RoutineRunner End(Enum id, Func<bool> action, int delayMS = _defaultDelay)
  328. {
  329. if (bAllowSubStepStart(id))
  330. {
  331. startNewStep(id, action);
  332. }
  333. else if (IsSubStepRunning(id))
  334. {
  335. if (_subStepTimer.ElapsedMilliseconds > delayMS)
  336. {
  337. Notify($"结束");
  338. _runnerState = RState.End;
  339. _subState = RState.End;
  340. _stopwatch.Stop();
  341. }
  342. }
  343. return this;
  344. }
  345. public RoutineRunner Delay(Enum id, int delayMS = _defaultDelay_5s)
  346. {
  347. return Run(id, () => { return true; }, delayMS);
  348. }
  349. public RoutineRunner DelayIf(Enum id, bool bRun, int delayMS = _defaultDelay_5s)
  350. {
  351. if (bRun)
  352. {
  353. return Run(id, () => { return true; }, delayMS);
  354. }
  355. return this;
  356. }
  357. public RoutineRunner Wait(Enum id, Func<bool> condition, int timeout = _defaultTimeout)
  358. {
  359. return Run(id, () => { return true; }, condition, timeout);
  360. }
  361. public RoutineRunner WaitIf (Enum id, bool bRun, Func<bool> condition, int timeout = _defaultTimeout)
  362. {
  363. if (bRun)
  364. {
  365. return Run(id, () => { return true; }, condition, timeout);
  366. }
  367. return this;
  368. }
  369. public RoutineRunner WaitWithStopCondition(Enum id, Func<bool> condition,Func<bool> stopCondition,int timeout=_defaultTimeout,bool error=true)
  370. {
  371. return Run(id, () => { return true; }, condition, stopCondition,timeout,error);
  372. }
  373. public RoutineRunner WaitWithStopConditionIf(Enum id, bool bRun, Func<bool> condition, Func<bool> stopCondition, int timeout = _defaultTimeout, bool error = true)
  374. {
  375. if (bRun)
  376. {
  377. return Run(id, () => { return true; }, condition, stopCondition, timeout, error);
  378. }
  379. return this;
  380. }
  381. public RoutineRunner LoopWait(Enum id,Func<bool> action,Func<bool> condition,Func<bool> fail)
  382. {
  383. if (bAllowSubStepStart(id))
  384. {
  385. startNewStep(id, action);
  386. }
  387. else if (IsSubStepRunning(id))
  388. {
  389. if(condition())
  390. {
  391. _subState = RState.End;
  392. }
  393. else if(fail())
  394. {
  395. Notify($"结束");
  396. _runnerState = RState.End;
  397. _subState = RState.End;
  398. }
  399. }
  400. return this;
  401. }
  402. public RoutineRunner LoopStart(Enum id, string name, int cycleCount, Func<bool> action, Func<bool> condition, int timeout = _defaultTimeout)
  403. {
  404. if(bAllowSubStepStart(id))
  405. {
  406. _loopName = name;
  407. _loopCounterSP = cycleCount;
  408. _loopCounter = 0;
  409. _isLoopMode = true;
  410. startNewLoopStep(id, action);
  411. }
  412. else if(bAllowLoopSubStepStart(id))
  413. {
  414. startNewLoopStep(id, action);
  415. }
  416. else if(IsSubStepRunning(id))
  417. {
  418. if (condition())
  419. {
  420. _subState = RState.End;
  421. }
  422. else if (_subStepTimer.ElapsedMilliseconds >= timeout)
  423. {
  424. Alarm($"Step:{id} 超时");
  425. _runnerState = _subState = RState.Timeout;
  426. _subStepTimer.Reset();
  427. }
  428. }
  429. return this;
  430. }
  431. public RoutineRunner LoopStart(Enum id, string name, int cycleCount, Func<bool> action, int delayMS = _defaultDelay)
  432. {
  433. if (bAllowSubStepStart(id))
  434. {
  435. _loopName = name;
  436. _loopCounterSP = cycleCount;
  437. _loopCounter = 0;
  438. _isLoopMode = true;
  439. startNewLoopStep(id, action);
  440. }
  441. else if (bAllowLoopSubStepStart(id))
  442. {
  443. startNewLoopStep(id, action);
  444. }
  445. else if (IsSubStepRunning(id))
  446. {
  447. if (_subStepTimer.ElapsedMilliseconds > delayMS)
  448. {
  449. _subState = RState.End;
  450. }
  451. }
  452. return this;
  453. }
  454. public RoutineRunner LoopRun(Enum id, Func<bool> action, Func<bool> condition, int timeout = _defaultTimeout)
  455. {
  456. if (bAllowLoopSubStepStart(id))
  457. {
  458. startNewLoopStep(id, action);
  459. }
  460. else if (IsSubStepRunning(id))
  461. {
  462. if (condition())
  463. {
  464. _subState = RState.End;
  465. }
  466. else if (_subStepTimer.ElapsedMilliseconds >= timeout)
  467. {
  468. Alarm($"Step:{id} 超时");
  469. _runnerState = _subState = RState.Timeout;
  470. _subStepTimer.Reset();
  471. }
  472. }
  473. return this;
  474. }
  475. public RoutineRunner LoopRunIf(Enum id, bool bRun, Func<bool> action, Func<bool> condition, int timeout = _defaultTimeout)
  476. {
  477. if(bRun)
  478. {
  479. return LoopRun(id, action, condition, timeout);
  480. }
  481. return this;
  482. }
  483. public RoutineRunner LoopRunIfWithStopStatus(Enum id, bool bRun,Func<bool> condition, Func<bool> failedCondition, int timeout = _defaultTimeout)
  484. {
  485. if (bRun)
  486. {
  487. if (bAllowLoopSubStepStart(id))
  488. {
  489. startNewLoopStep(id, () => { return true; });
  490. }
  491. else if (IsSubStepRunning(id))
  492. {
  493. if (condition())
  494. {
  495. _subState = RState.End;
  496. }
  497. else if (failedCondition())
  498. {
  499. _runnerState = _subState = RState.Failed;
  500. }
  501. else
  502. {
  503. if (_subStepTimer.ElapsedMilliseconds >= timeout)
  504. {
  505. Alarm($"Step:{id} 超时", true);
  506. _runnerState = _subState = RState.Timeout;
  507. _subStepTimer.Reset();
  508. }
  509. }
  510. }
  511. }
  512. return this;
  513. }
  514. public RoutineRunner LoopRun(Enum id, Func<bool> action, int delayMS = _defaultDelay)
  515. {
  516. if (bAllowLoopSubStepStart(id))
  517. {
  518. startNewLoopStep(id, action);
  519. }
  520. else if (IsSubStepRunning(id))
  521. {
  522. if (_subStepTimer.ElapsedMilliseconds > delayMS)
  523. {
  524. _subState = RState.End;
  525. }
  526. }
  527. return this;
  528. }
  529. public RoutineRunner LoopRunOnlyTimeOutFault(Enum id, Func<bool> action, int delayMS = _defaultDelay)
  530. {
  531. if (bAllowLoopSubStepStart(id))
  532. {
  533. startNewLoopStep(id, () => { return true; });
  534. }
  535. else if (IsSubStepRunning(id))
  536. {
  537. if (_subStepTimer.ElapsedMilliseconds > delayMS)
  538. {
  539. if (!action())
  540. {
  541. Alarm($"{_loopCounter + 1}th [{_loopName}] Loop Step: {id} failed");
  542. _runnerState = _subState = RState.Failed;
  543. _subStepTimer.Reset();
  544. }
  545. else
  546. {
  547. _subState = RState.End;
  548. }
  549. }
  550. }
  551. return this;
  552. }
  553. public RoutineRunner LoopRunIfOnlyTimeOutFault(Enum id, bool bRun, Func<bool> action, int delayMS = _defaultDelay)
  554. {
  555. if (bRun)
  556. {
  557. return LoopRunOnlyTimeOutFault(id, action, delayMS);
  558. }
  559. return this;
  560. }
  561. public RoutineRunner LoopRunIf(Enum id, bool bRun, Func<bool> action, int delayMS = _defaultDelay)
  562. {
  563. if(bRun)
  564. {
  565. return LoopRun(id, action, delayMS);
  566. }
  567. return this;
  568. }
  569. public RoutineRunner LoopRunWithStopStatus(Enum id, Func<bool> condition, Func<bool> failedCondition, int timeout = _defaultTimeout)
  570. {
  571. if (bAllowLoopSubStepStart(id))
  572. {
  573. startNewLoopStep(id, () => { return true; });
  574. }
  575. else if (IsSubStepRunning(id))
  576. {
  577. if (condition())
  578. {
  579. _subState = RState.End;
  580. }
  581. else if (failedCondition())
  582. {
  583. _runnerState = _subState = RState.Failed;
  584. }
  585. else
  586. {
  587. if (_subStepTimer.ElapsedMilliseconds >= timeout)
  588. {
  589. Alarm($"Step:{id} 超时", true);
  590. _runnerState = _subState = RState.Timeout;
  591. _subStepTimer.Reset();
  592. }
  593. }
  594. }
  595. return this;
  596. }
  597. public RoutineRunner LoopEnd(Enum id, Func<bool> action, Func<bool> condition, int timeout = _defaultTimeout)
  598. {
  599. if (bAllowLoopSubStepStart(id))
  600. {
  601. startNewLoopStep(id, action);
  602. }
  603. else if (IsSubStepRunning(id))
  604. {
  605. if (condition())
  606. {
  607. Notify($"{_loopCounter + 1}th [{_loopName}] Loop End");
  608. _subState = RState.End;
  609. _loopCounter++;
  610. if (_loopCounter >= _loopCounterSP)
  611. {
  612. foreach (var lid in _loopSteps)
  613. _steps.Push(lid);
  614. _loopSteps.Clear();
  615. _isLoopMode = false;
  616. }
  617. }
  618. else if (_subStepTimer.ElapsedMilliseconds >= timeout)
  619. {
  620. Alarm($"Step:{id} 超时");
  621. _runnerState = _subState = RState.Timeout;
  622. _subStepTimer.Reset();
  623. }
  624. }
  625. return this;
  626. }
  627. public RoutineRunner LoopEnd(Enum id, Func<bool> action, int delayMS = _defaultDelay)
  628. {
  629. if (bAllowLoopSubStepStart(id))
  630. {
  631. startNewLoopStep(id, action);
  632. }
  633. else if (IsSubStepRunning(id))
  634. {
  635. if (_subStepTimer.ElapsedMilliseconds > delayMS)
  636. {
  637. Notify($"{_loopCounter + 1}th [{_loopName}] Loop End");
  638. _subState = RState.End;
  639. _loopCounter++;
  640. if (_loopCounter >= _loopCounterSP)
  641. {
  642. foreach (var lid in _loopSteps)
  643. _steps.Push(lid);
  644. _loopSteps.Clear();
  645. _isLoopMode = false;
  646. }
  647. }
  648. }
  649. return this;
  650. }
  651. public RoutineRunner LoopDelay(Enum id, int delayMS)
  652. {
  653. return LoopRun(id, () => { return true; }, delayMS);
  654. }
  655. public RoutineRunner LoopRunDelay(Enum id, Func<bool> action, int delayMS)
  656. {
  657. return LoopRun(id, action, delayMS);
  658. }
  659. public RoutineRunner LoopWait(Enum id, Func<bool> condition, int timeout = _defaultTimeout)
  660. {
  661. return LoopRun(id, () => { return true; }, condition, timeout);
  662. }
  663. public RoutineRunner LoopWaitIf(Enum id, bool bRun, Func<bool> condition, int timeout = _defaultTimeout)
  664. {
  665. if (bRun)
  666. {
  667. return LoopRun(id, () => { return true; }, condition, timeout);
  668. }
  669. return this;
  670. }
  671. public RoutineRunner LoopRetryStart(Enum id,string name, int cycleCount, Func<bool> action, int delayMS = _defaultDelay)
  672. {
  673. if (bAllowSubStepStart(id))
  674. {
  675. _loopName = name;
  676. _loopCounterSP = cycleCount;
  677. _loopCounter = 0;
  678. _isLoopMode = true;
  679. _loopSteps.Clear();
  680. startNewLoopStep(id, action);
  681. }
  682. else if (bAllowLoopSubStepStart(id)&&!_loopSteps.Contains(id))
  683. {
  684. startNewLoopStep(id, action);
  685. }
  686. else if (IsSubStepRunning(id))
  687. {
  688. if (_subStepTimer.ElapsedMilliseconds > delayMS)
  689. {
  690. _subState = RState.End;
  691. }
  692. }
  693. return this;
  694. }
  695. public RoutineRunner LoopRetrySecondRun(Enum id, Func<bool> action, Func<bool> condition, int timeout = _defaultTimeout)
  696. {
  697. if (_loopCounter > _loopCounterSP)
  698. {
  699. return this;
  700. }
  701. if (bAllowLoopSubStepStart(id)&&_loopCounter>=1&&_loopSteps.Count!=0&&!_loopSteps.Contains(id))
  702. {
  703. startNewLoopStep(id, action);
  704. }
  705. else if (IsSubStepRunning(id))
  706. {
  707. if (condition())
  708. {
  709. _subState = RState.End;
  710. }
  711. else if (_subStepTimer.ElapsedMilliseconds >= timeout)
  712. {
  713. Alarm($"Step:{id} 超时");
  714. _runnerState = _subState = RState.Timeout;
  715. _subStepTimer.Reset();
  716. }
  717. }
  718. return this;
  719. }
  720. public RoutineRunner LoopRetrySecondRunWithStopStatus(Enum id, Func<bool> condition, Func<bool> failedCondition, int timeout = _defaultTimeout)
  721. {
  722. if (_loopCounter > _loopCounterSP)
  723. {
  724. return this;
  725. }
  726. if (bAllowLoopSubStepStart(id)&&_loopCounter>=1 && _loopSteps.Count != 0 && !_loopSteps.Contains(id))
  727. {
  728. startNewLoopStep(id, () => { return true; });
  729. }
  730. else if (IsSubStepRunning(id))
  731. {
  732. if (condition())
  733. {
  734. _subState = RState.End;
  735. }
  736. else if (failedCondition())
  737. {
  738. _runnerState = _subState = RState.Failed;
  739. }
  740. else
  741. {
  742. if (_subStepTimer.ElapsedMilliseconds >= timeout)
  743. {
  744. Alarm($"Step:{id} 超时", true);
  745. _runnerState = _subState = RState.Timeout;
  746. _subStepTimer.Reset();
  747. }
  748. }
  749. }
  750. return this;
  751. }
  752. public RoutineRunner LoopRetryRun(Enum id, Func<bool> action, Func<bool> condition, int timeout = _defaultTimeout)
  753. {
  754. if (_loopCounter > _loopCounterSP)
  755. {
  756. return this;
  757. }
  758. if (bAllowLoopSubStepStart(id) && _loopSteps.Count != 0 && !_loopSteps.Contains(id))
  759. {
  760. startNewLoopStep(id, action);
  761. }
  762. else if (IsSubStepRunning(id))
  763. {
  764. if (condition())
  765. {
  766. _subState = RState.End;
  767. }
  768. else if (_subStepTimer.ElapsedMilliseconds >= timeout)
  769. {
  770. Alarm($"Step:{id} 超时");
  771. _runnerState = _subState = RState.Timeout;
  772. _subStepTimer.Reset();
  773. }
  774. }
  775. return this;
  776. }
  777. public RoutineRunner LoopRetryRunBack(Enum id, Func<bool> action, Func<bool> condition, int timeout = _defaultTimeout)
  778. {
  779. if (_loopCounter > _loopCounterSP)
  780. {
  781. return this;
  782. }
  783. if (bAllowLoopSubStepStart(id) && _loopSteps.Count != 0 && !_loopSteps.Contains(id))
  784. {
  785. startNewLoopStep(id, action);
  786. }
  787. else if (IsSubStepRunning(id))
  788. {
  789. if (condition())
  790. {
  791. _subState = RState.End;
  792. }
  793. else if (_subStepTimer.ElapsedMilliseconds >= timeout)
  794. {
  795. _subState = RState.End;
  796. _loopCounter++;
  797. if (_loopCounter <= _loopCounterSP)
  798. {
  799. _loopSteps.Clear();
  800. }
  801. _subStepTimer.Reset();
  802. }
  803. }
  804. return this;
  805. }
  806. public RoutineRunner LoopRetryWait(Enum id, Func<bool> condition, int timeout = _defaultTimeout)
  807. {
  808. if (_loopCounter > _loopCounterSP)
  809. {
  810. return this;
  811. }
  812. return LoopRetryRun(id, () => { return true; }, condition, timeout);
  813. }
  814. public RoutineRunner LoopRetryWaitBack(Enum id, Func<bool> condition, int timeout = _defaultTimeout)
  815. {
  816. if (_loopCounter > _loopCounterSP)
  817. {
  818. return this;
  819. }
  820. if (bAllowLoopSubStepStart(id) && _loopSteps.Count != 0 && !_loopSteps.Contains(id))
  821. {
  822. startNewLoopStep(id, () => { return true; });
  823. }
  824. else if (IsSubStepRunning(id))
  825. {
  826. if (condition())
  827. {
  828. _subState = RState.End;
  829. }
  830. else if (_subStepTimer.ElapsedMilliseconds >= timeout)
  831. {
  832. _subState = RState.End;
  833. _loopCounter++;
  834. if (_loopCounter <= _loopCounterSP)
  835. {
  836. _loopSteps.Clear();
  837. }
  838. _subStepTimer.Reset();
  839. }
  840. }
  841. return this;
  842. }
  843. public RoutineRunner LoopRetryDelay(Enum id, int delayMS)
  844. {
  845. return LoopRetryRun(id, () => { return true; },()=> { return true; }, delayMS);
  846. }
  847. public RoutineRunner LoopRetryRunWithStopStatus(Enum id, Func<bool> condition, Func<bool> failedCondition, int timeout = _defaultTimeout)
  848. {
  849. if (_loopCounter > _loopCounterSP)
  850. {
  851. return this;
  852. }
  853. if (bAllowLoopSubStepStart(id) && _loopSteps.Count != 0 && !_loopSteps.Contains(id))
  854. {
  855. startNewLoopStep(id, () => { return true; });
  856. }
  857. else if (IsSubStepRunning(id))
  858. {
  859. if (condition())
  860. {
  861. _subState = RState.End;
  862. }
  863. else if (failedCondition())
  864. {
  865. _runnerState = _subState = RState.Failed;
  866. }
  867. else
  868. {
  869. if (_subStepTimer.ElapsedMilliseconds >= timeout)
  870. {
  871. Alarm($"Step:{id} 超时", true);
  872. _runnerState = _subState = RState.Timeout;
  873. _subStepTimer.Reset();
  874. }
  875. }
  876. }
  877. return this;
  878. }
  879. public RoutineRunner LoopRetryRunWithStopStatusBack(Enum id, Func<bool> condition, Func<bool> failedCondition, int timeout = _defaultTimeout)
  880. {
  881. if (_loopCounter > _loopCounterSP)
  882. {
  883. return this;
  884. }
  885. if (bAllowLoopSubStepStart(id) && _loopSteps.Count != 0 && !_loopSteps.Contains(id))
  886. {
  887. startNewLoopStep(id, () => { return true; });
  888. }
  889. else if (IsSubStepRunning(id))
  890. {
  891. if (condition())
  892. {
  893. _subState = RState.End;
  894. }
  895. else if (failedCondition())
  896. {
  897. _subState = RState.End;
  898. _loopCounter++;
  899. if (_loopCounter <= _loopCounterSP)
  900. {
  901. _loopSteps.Clear();
  902. }
  903. _subStepTimer.Reset();
  904. }
  905. else
  906. {
  907. if (_subStepTimer.ElapsedMilliseconds >= timeout)
  908. {
  909. _subState = RState.End;
  910. _loopCounter++;
  911. if (_loopCounter <= _loopCounterSP)
  912. {
  913. _loopSteps.Clear();
  914. }
  915. _subStepTimer.Reset();
  916. }
  917. }
  918. }
  919. return this;
  920. }
  921. public RoutineRunner LoopRetryEnd(Enum id, int delayMS = _defaultDelay)
  922. {
  923. if (bAllowLoopSubStepStart(id)&& _loopSteps.Count != 0 && !_loopSteps.Contains(id))
  924. {
  925. startNewLoopStep(id, () => { return true; });
  926. }
  927. else if (IsSubStepRunning(id))
  928. {
  929. foreach (var lid in _loopSteps)
  930. _steps.Push(lid);
  931. if (_loopCounter > _loopCounterSP)
  932. {
  933. Alarm($"Step:{id} Retry times over {_loopCounterSP}");
  934. _runnerState = _subState = RState.Timeout;
  935. _subStepTimer.Reset();
  936. }
  937. else
  938. {
  939. _subState = RState.End;
  940. }
  941. _loopSteps.Clear();
  942. _isLoopMode = false;
  943. }
  944. return this;
  945. }
  946. private void startNewStep(Enum id, Func<bool> action,bool error=true)
  947. {
  948. if (action())
  949. {
  950. Notify($"Step: {id} start ---");
  951. _steps.Push(id);
  952. _curStep = id;
  953. _subState = RState.Running;
  954. _subStepTimer.Restart();
  955. }
  956. else
  957. {
  958. Alarm($"Step: {id} failed ",error);
  959. _runnerState = RState.Failed;
  960. }
  961. }
  962. private void startNewLoopStep(Enum id, Func<bool> action)
  963. {
  964. if (action())
  965. {
  966. Notify($"{_loopCounter + 1}th [{_loopName}] Loop Step: {id} start ---");
  967. if (!_loopSteps.Contains(id))
  968. _loopSteps.Push(id);
  969. _curStep = id;
  970. _subState = RState.Running;
  971. _subStepTimer.Restart();
  972. }
  973. else
  974. {
  975. Alarm($"{_loopCounter + 1}th [{_loopName}] Loop Step: {id} failed");
  976. _runnerState = RState.Failed;
  977. }
  978. }
  979. protected void Notify(string message)
  980. {
  981. LOG.WriteLog(eEvent.EV_ROUTINE_NOTIFY, _module, _name, message);
  982. }
  983. protected void Alarm(string message,bool error=true)
  984. {
  985. if (error)
  986. {
  987. _errorMsg= message;
  988. LOG.WriteLog(eEvent.ERR_ROUTINE_FAILED, _module,_name,message);
  989. }
  990. else
  991. {
  992. LOG.WriteLog(eEvent.EV_ROUTINE_NOTIFY, _module, _name,message);
  993. }
  994. }
  995. }
  996. static public class HOFs
  997. {
  998. public static Func<R> Apply<T1, R>(this Func<T1, R> func, T1 t1)
  999. => () => func(t1);
  1000. public static Func<R> Apply<T1, T2, R>(this Func<T1, T2, R> func, T1 t1, T2 t2)
  1001. => () => func(t1, t2);
  1002. public static Func<R> Apply<T1, T2, T3, R>(this Func<T1, T2, T3, R> func, T1 t1, T2 t2, T3 t3)
  1003. => () => func(t1, t2, t3);
  1004. public static Func<bool> WrapAction(this Action action)
  1005. => () => { action(); return true; };
  1006. public static Func<bool> WrapAction<T1>(this Action<T1> action, T1 t1)
  1007. => () => { action(t1); return true; };
  1008. public static Func<bool> WrapAction<T1, T2>(this Action<T1, T2> action, T1 t1, T2 t2)
  1009. => () => { action(t1, t2); return true; };
  1010. public static Func<bool> WrapAction<T1, T2, T3>(this Action<T1, T2, T3> action, T1 t1, T2 t2, T3 t3)
  1011. => () => { action(t1, t2, t3); return true; };
  1012. }
  1013. }