WorkItemsGroupBase.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471
  1. using System;
  2. using System.Threading;
  3. namespace Amib.Threading.Internal
  4. {
  5. public abstract class WorkItemsGroupBase : IWorkItemsGroup
  6. {
  7. #region Private Fields
  8. /// <summary>
  9. /// Contains the name of this instance of SmartThreadPool.
  10. /// Can be changed by the user.
  11. /// </summary>
  12. private string _name = "WorkItemsGroupBase";
  13. public WorkItemsGroupBase()
  14. {
  15. IsIdle = true;
  16. }
  17. #endregion
  18. #region IWorkItemsGroup Members
  19. #region Public Methods
  20. /// <summary>
  21. /// Get/Set the name of the SmartThreadPool/WorkItemsGroup instance
  22. /// </summary>
  23. public string Name
  24. {
  25. get { return _name; }
  26. set { _name = value; }
  27. }
  28. #endregion
  29. #region Abstract Methods
  30. public abstract int Concurrency { get; set; }
  31. public abstract int WaitingCallbacks { get; }
  32. public abstract object[] GetStates();
  33. public abstract WIGStartInfo WIGStartInfo { get; }
  34. public abstract void Start();
  35. public abstract void Cancel(bool abortExecution);
  36. public abstract bool WaitForIdle(int millisecondsTimeout);
  37. public abstract event WorkItemsGroupIdleHandler OnIdle;
  38. internal abstract void Enqueue(WorkItem workItem);
  39. internal virtual void PreQueueWorkItem() { }
  40. #endregion
  41. #region Common Base Methods
  42. /// <summary>
  43. /// Cancel all the work items.
  44. /// Same as Cancel(false)
  45. /// </summary>
  46. public virtual void Cancel()
  47. {
  48. Cancel(false);
  49. }
  50. /// <summary>
  51. /// Wait for the SmartThreadPool/WorkItemsGroup to be idle
  52. /// </summary>
  53. public void WaitForIdle()
  54. {
  55. WaitForIdle(Timeout.Infinite);
  56. }
  57. /// <summary>
  58. /// Wait for the SmartThreadPool/WorkItemsGroup to be idle
  59. /// </summary>
  60. public bool WaitForIdle(TimeSpan timeout)
  61. {
  62. return WaitForIdle((int)timeout.TotalMilliseconds);
  63. }
  64. /// <summary>
  65. /// IsIdle is true when there are no work items running or queued.
  66. /// </summary>
  67. public bool IsIdle { get; protected set; }
  68. #endregion
  69. #region QueueWorkItem
  70. /// <summary>
  71. /// Queue a work item
  72. /// </summary>
  73. /// <param name="callback">A callback to execute</param>
  74. /// <returns>Returns a work item result</returns>
  75. public IWorkItemResult QueueWorkItem(WorkItemCallback callback)
  76. {
  77. WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback);
  78. Enqueue(workItem);
  79. return workItem.GetWorkItemResult();
  80. }
  81. /// <summary>
  82. /// Queue a work item
  83. /// </summary>
  84. /// <param name="callback">A callback to execute</param>
  85. /// <param name="workItemPriority">The priority of the work item</param>
  86. /// <returns>Returns a work item result</returns>
  87. public IWorkItemResult QueueWorkItem(WorkItemCallback callback, WorkItemPriority workItemPriority)
  88. {
  89. PreQueueWorkItem();
  90. WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, workItemPriority);
  91. Enqueue(workItem);
  92. return workItem.GetWorkItemResult();
  93. }
  94. /// <summary>
  95. /// Queue a work item
  96. /// </summary>
  97. /// <param name="workItemInfo">Work item info</param>
  98. /// <param name="callback">A callback to execute</param>
  99. /// <returns>Returns a work item result</returns>
  100. public IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback)
  101. {
  102. PreQueueWorkItem();
  103. WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, workItemInfo, callback);
  104. Enqueue(workItem);
  105. return workItem.GetWorkItemResult();
  106. }
  107. /// <summary>
  108. /// Queue a work item
  109. /// </summary>
  110. /// <param name="callback">A callback to execute</param>
  111. /// <param name="state">
  112. /// The context object of the work item. Used for passing arguments to the work item.
  113. /// </param>
  114. /// <returns>Returns a work item result</returns>
  115. public IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state)
  116. {
  117. WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state);
  118. Enqueue(workItem);
  119. return workItem.GetWorkItemResult();
  120. }
  121. /// <summary>
  122. /// Queue a work item
  123. /// </summary>
  124. /// <param name="callback">A callback to execute</param>
  125. /// <param name="state">
  126. /// The context object of the work item. Used for passing arguments to the work item.
  127. /// </param>
  128. /// <param name="workItemPriority">The work item priority</param>
  129. /// <returns>Returns a work item result</returns>
  130. public IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, WorkItemPriority workItemPriority)
  131. {
  132. PreQueueWorkItem();
  133. WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, workItemPriority);
  134. Enqueue(workItem);
  135. return workItem.GetWorkItemResult();
  136. }
  137. /// <summary>
  138. /// Queue a work item
  139. /// </summary>
  140. /// <param name="workItemInfo">Work item information</param>
  141. /// <param name="callback">A callback to execute</param>
  142. /// <param name="state">
  143. /// The context object of the work item. Used for passing arguments to the work item.
  144. /// </param>
  145. /// <returns>Returns a work item result</returns>
  146. public IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback, object state)
  147. {
  148. PreQueueWorkItem();
  149. WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, workItemInfo, callback, state);
  150. Enqueue(workItem);
  151. return workItem.GetWorkItemResult();
  152. }
  153. /// <summary>
  154. /// Queue a work item
  155. /// </summary>
  156. /// <param name="callback">A callback to execute</param>
  157. /// <param name="state">
  158. /// The context object of the work item. Used for passing arguments to the work item.
  159. /// </param>
  160. /// <param name="postExecuteWorkItemCallback">
  161. /// A delegate to call after the callback completion
  162. /// </param>
  163. /// <returns>Returns a work item result</returns>
  164. public IWorkItemResult QueueWorkItem(
  165. WorkItemCallback callback,
  166. object state,
  167. PostExecuteWorkItemCallback postExecuteWorkItemCallback)
  168. {
  169. PreQueueWorkItem();
  170. WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, postExecuteWorkItemCallback);
  171. Enqueue(workItem);
  172. return workItem.GetWorkItemResult();
  173. }
  174. /// <summary>
  175. /// Queue a work item
  176. /// </summary>
  177. /// <param name="callback">A callback to execute</param>
  178. /// <param name="state">
  179. /// The context object of the work item. Used for passing arguments to the work item.
  180. /// </param>
  181. /// <param name="postExecuteWorkItemCallback">
  182. /// A delegate to call after the callback completion
  183. /// </param>
  184. /// <param name="workItemPriority">The work item priority</param>
  185. /// <returns>Returns a work item result</returns>
  186. public IWorkItemResult QueueWorkItem(
  187. WorkItemCallback callback,
  188. object state,
  189. PostExecuteWorkItemCallback postExecuteWorkItemCallback,
  190. WorkItemPriority workItemPriority)
  191. {
  192. PreQueueWorkItem();
  193. WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, postExecuteWorkItemCallback, workItemPriority);
  194. Enqueue(workItem);
  195. return workItem.GetWorkItemResult();
  196. }
  197. /// <summary>
  198. /// Queue a work item
  199. /// </summary>
  200. /// <param name="callback">A callback to execute</param>
  201. /// <param name="state">
  202. /// The context object of the work item. Used for passing arguments to the work item.
  203. /// </param>
  204. /// <param name="postExecuteWorkItemCallback">
  205. /// A delegate to call after the callback completion
  206. /// </param>
  207. /// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
  208. /// <returns>Returns a work item result</returns>
  209. public IWorkItemResult QueueWorkItem(
  210. WorkItemCallback callback,
  211. object state,
  212. PostExecuteWorkItemCallback postExecuteWorkItemCallback,
  213. CallToPostExecute callToPostExecute)
  214. {
  215. PreQueueWorkItem();
  216. WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, postExecuteWorkItemCallback, callToPostExecute);
  217. Enqueue(workItem);
  218. return workItem.GetWorkItemResult();
  219. }
  220. /// <summary>
  221. /// Queue a work item
  222. /// </summary>
  223. /// <param name="callback">A callback to execute</param>
  224. /// <param name="state">
  225. /// The context object of the work item. Used for passing arguments to the work item.
  226. /// </param>
  227. /// <param name="postExecuteWorkItemCallback">
  228. /// A delegate to call after the callback completion
  229. /// </param>
  230. /// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
  231. /// <param name="workItemPriority">The work item priority</param>
  232. /// <returns>Returns a work item result</returns>
  233. public IWorkItemResult QueueWorkItem(
  234. WorkItemCallback callback,
  235. object state,
  236. PostExecuteWorkItemCallback postExecuteWorkItemCallback,
  237. CallToPostExecute callToPostExecute,
  238. WorkItemPriority workItemPriority)
  239. {
  240. PreQueueWorkItem();
  241. WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, postExecuteWorkItemCallback, callToPostExecute, workItemPriority);
  242. Enqueue(workItem);
  243. return workItem.GetWorkItemResult();
  244. }
  245. #endregion
  246. #region QueueWorkItem(Action<...>)
  247. public IWorkItemResult QueueWorkItem(Action action)
  248. {
  249. return QueueWorkItem (action, SmartThreadPool.DefaultWorkItemPriority);
  250. }
  251. public IWorkItemResult QueueWorkItem (Action action, WorkItemPriority priority)
  252. {
  253. PreQueueWorkItem ();
  254. WorkItem workItem = WorkItemFactory.CreateWorkItem (
  255. this,
  256. WIGStartInfo,
  257. delegate
  258. {
  259. action.Invoke ();
  260. return null;
  261. }, priority);
  262. Enqueue (workItem);
  263. return workItem.GetWorkItemResult ();
  264. }
  265. public IWorkItemResult QueueWorkItem<T>(Action<T> action, T arg)
  266. {
  267. return QueueWorkItem<T> (action, arg, SmartThreadPool.DefaultWorkItemPriority);
  268. }
  269. public IWorkItemResult QueueWorkItem<T> (Action<T> action, T arg, WorkItemPriority priority)
  270. {
  271. PreQueueWorkItem ();
  272. WorkItem workItem = WorkItemFactory.CreateWorkItem (
  273. this,
  274. WIGStartInfo,
  275. state =>
  276. {
  277. action.Invoke (arg);
  278. return null;
  279. },
  280. WIGStartInfo.FillStateWithArgs ? new object[] { arg } : null, priority);
  281. Enqueue (workItem);
  282. return workItem.GetWorkItemResult ();
  283. }
  284. public IWorkItemResult QueueWorkItem<T1, T2>(Action<T1, T2> action, T1 arg1, T2 arg2)
  285. {
  286. return QueueWorkItem<T1, T2> (action, arg1, arg2, SmartThreadPool.DefaultWorkItemPriority);
  287. }
  288. public IWorkItemResult QueueWorkItem<T1, T2> (Action<T1, T2> action, T1 arg1, T2 arg2, WorkItemPriority priority)
  289. {
  290. PreQueueWorkItem ();
  291. WorkItem workItem = WorkItemFactory.CreateWorkItem (
  292. this,
  293. WIGStartInfo,
  294. state =>
  295. {
  296. action.Invoke (arg1, arg2);
  297. return null;
  298. },
  299. WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2 } : null, priority);
  300. Enqueue (workItem);
  301. return workItem.GetWorkItemResult ();
  302. }
  303. public IWorkItemResult QueueWorkItem<T1, T2, T3>(Action<T1, T2, T3> action, T1 arg1, T2 arg2, T3 arg3)
  304. {
  305. return QueueWorkItem<T1, T2, T3> (action, arg1, arg2, arg3, SmartThreadPool.DefaultWorkItemPriority);
  306. ;
  307. }
  308. public IWorkItemResult QueueWorkItem<T1, T2, T3> (Action<T1, T2, T3> action, T1 arg1, T2 arg2, T3 arg3, WorkItemPriority priority)
  309. {
  310. PreQueueWorkItem ();
  311. WorkItem workItem = WorkItemFactory.CreateWorkItem (
  312. this,
  313. WIGStartInfo,
  314. state =>
  315. {
  316. action.Invoke (arg1, arg2, arg3);
  317. return null;
  318. },
  319. WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3 } : null, priority);
  320. Enqueue (workItem);
  321. return workItem.GetWorkItemResult ();
  322. }
  323. public IWorkItemResult QueueWorkItem<T1, T2, T3, T4>(
  324. Action<T1, T2, T3, T4> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
  325. {
  326. return QueueWorkItem<T1, T2, T3, T4> (action, arg1, arg2, arg3, arg4,
  327. SmartThreadPool.DefaultWorkItemPriority);
  328. }
  329. public IWorkItemResult QueueWorkItem<T1, T2, T3, T4> (
  330. Action<T1, T2, T3, T4> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4, WorkItemPriority priority)
  331. {
  332. PreQueueWorkItem ();
  333. WorkItem workItem = WorkItemFactory.CreateWorkItem (
  334. this,
  335. WIGStartInfo,
  336. state =>
  337. {
  338. action.Invoke (arg1, arg2, arg3, arg4);
  339. return null;
  340. },
  341. WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3, arg4 } : null, priority);
  342. Enqueue (workItem);
  343. return workItem.GetWorkItemResult ();
  344. }
  345. #endregion
  346. #region QueueWorkItem(Func<...>)
  347. public IWorkItemResult<TResult> QueueWorkItem<TResult>(Func<TResult> func)
  348. {
  349. PreQueueWorkItem();
  350. WorkItem workItem = WorkItemFactory.CreateWorkItem(
  351. this,
  352. WIGStartInfo,
  353. state =>
  354. {
  355. return func.Invoke();
  356. });
  357. Enqueue(workItem);
  358. return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult());
  359. }
  360. public IWorkItemResult<TResult> QueueWorkItem<T, TResult>(Func<T, TResult> func, T arg)
  361. {
  362. PreQueueWorkItem();
  363. WorkItem workItem = WorkItemFactory.CreateWorkItem(
  364. this,
  365. WIGStartInfo,
  366. state =>
  367. {
  368. return func.Invoke(arg);
  369. },
  370. WIGStartInfo.FillStateWithArgs ? new object[] { arg } : null);
  371. Enqueue(workItem);
  372. return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult());
  373. }
  374. public IWorkItemResult<TResult> QueueWorkItem<T1, T2, TResult>(Func<T1, T2, TResult> func, T1 arg1, T2 arg2)
  375. {
  376. PreQueueWorkItem();
  377. WorkItem workItem = WorkItemFactory.CreateWorkItem(
  378. this,
  379. WIGStartInfo,
  380. state =>
  381. {
  382. return func.Invoke(arg1, arg2);
  383. },
  384. WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2 } : null);
  385. Enqueue(workItem);
  386. return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult());
  387. }
  388. public IWorkItemResult<TResult> QueueWorkItem<T1, T2, T3, TResult>(
  389. Func<T1, T2, T3, TResult> func, T1 arg1, T2 arg2, T3 arg3)
  390. {
  391. PreQueueWorkItem();
  392. WorkItem workItem = WorkItemFactory.CreateWorkItem(
  393. this,
  394. WIGStartInfo,
  395. state =>
  396. {
  397. return func.Invoke(arg1, arg2, arg3);
  398. },
  399. WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3 } : null);
  400. Enqueue(workItem);
  401. return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult());
  402. }
  403. public IWorkItemResult<TResult> QueueWorkItem<T1, T2, T3, T4, TResult>(
  404. Func<T1, T2, T3, T4, TResult> func, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
  405. {
  406. PreQueueWorkItem();
  407. WorkItem workItem = WorkItemFactory.CreateWorkItem(
  408. this,
  409. WIGStartInfo,
  410. state =>
  411. {
  412. return func.Invoke(arg1, arg2, arg3, arg4);
  413. },
  414. WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3, arg4 } : null);
  415. Enqueue(workItem);
  416. return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult());
  417. }
  418. #endregion
  419. #endregion
  420. }
  421. }