WorkItemsGroupBase.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  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. public IWorkItemResult QueueWorkItem(WaitCallback callback)
  71. {
  72. WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, null);
  73. Enqueue(workItem);
  74. return workItem.GetWorkItemResult();
  75. }
  76. public IWorkItemResult QueueWorkItem(WaitCallback callback, object state)
  77. {
  78. WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state);
  79. Enqueue(workItem);
  80. return workItem.GetWorkItemResult();
  81. }
  82. public IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WaitCallback callback)
  83. {
  84. PreQueueWorkItem();
  85. WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, workItemInfo, callback, null);
  86. Enqueue(workItem);
  87. return workItem.GetWorkItemResult();
  88. }
  89. public IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WaitCallback callback, object state)
  90. {
  91. PreQueueWorkItem();
  92. WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, workItemInfo, callback, state);
  93. Enqueue(workItem);
  94. return workItem.GetWorkItemResult();
  95. }
  96. /// <summary>
  97. /// Queue a work item
  98. /// </summary>
  99. /// <param name="callback">A callback to execute</param>
  100. /// <returns>Returns a work item result</returns>
  101. public IWorkItemResult QueueWorkItem(WorkItemCallback callback)
  102. {
  103. WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback);
  104. Enqueue(workItem);
  105. return workItem.GetWorkItemResult();
  106. }
  107. /// <summary>
  108. /// Queue a work item
  109. /// </summary>
  110. /// <param name="workItemInfo">Work item info</param>
  111. /// <param name="callback">A callback to execute</param>
  112. /// <returns>Returns a work item result</returns>
  113. public IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback)
  114. {
  115. PreQueueWorkItem();
  116. WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, workItemInfo, callback);
  117. Enqueue(workItem);
  118. return workItem.GetWorkItemResult();
  119. }
  120. /// <summary>
  121. /// Queue a work item
  122. /// </summary>
  123. /// <param name="callback">A callback to execute</param>
  124. /// <param name="state">
  125. /// The context object of the work item. Used for passing arguments to the work item.
  126. /// </param>
  127. /// <returns>Returns a work item result</returns>
  128. public IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state)
  129. {
  130. WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state);
  131. Enqueue(workItem);
  132. return workItem.GetWorkItemResult();
  133. }
  134. /// <summary>
  135. /// Queue a work item
  136. /// </summary>
  137. /// <param name="workItemInfo">Work item information</param>
  138. /// <param name="callback">A callback to execute</param>
  139. /// <param name="state">
  140. /// The context object of the work item. Used for passing arguments to the work item.
  141. /// </param>
  142. /// <returns>Returns a work item result</returns>
  143. public IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback, object state)
  144. {
  145. PreQueueWorkItem();
  146. WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, workItemInfo, callback, state);
  147. Enqueue(workItem);
  148. return workItem.GetWorkItemResult();
  149. }
  150. /// <summary>
  151. /// Queue a work item
  152. /// </summary>
  153. /// <param name="callback">A callback to execute</param>
  154. /// <param name="state">
  155. /// The context object of the work item. Used for passing arguments to the work item.
  156. /// </param>
  157. /// <param name="postExecuteWorkItemCallback">
  158. /// A delegate to call after the callback completion
  159. /// </param>
  160. /// <returns>Returns a work item result</returns>
  161. public IWorkItemResult QueueWorkItem( WorkItemCallback callback, object state,
  162. PostExecuteWorkItemCallback postExecuteWorkItemCallback)
  163. {
  164. PreQueueWorkItem();
  165. WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, postExecuteWorkItemCallback);
  166. Enqueue(workItem);
  167. return workItem.GetWorkItemResult();
  168. }
  169. /// <summary>
  170. /// Queue a work item
  171. /// </summary>
  172. /// <param name="callback">A callback to execute</param>
  173. /// <param name="state">
  174. /// The context object of the work item. Used for passing arguments to the work item.
  175. /// </param>
  176. /// <param name="postExecuteWorkItemCallback">
  177. /// A delegate to call after the callback completion
  178. /// </param>
  179. /// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
  180. /// <returns>Returns a work item result</returns>
  181. public IWorkItemResult QueueWorkItem( WorkItemCallback callback, object state,
  182. PostExecuteWorkItemCallback postExecuteWorkItemCallback, CallToPostExecute callToPostExecute)
  183. {
  184. PreQueueWorkItem();
  185. WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, postExecuteWorkItemCallback, callToPostExecute);
  186. Enqueue(workItem);
  187. return workItem.GetWorkItemResult();
  188. }
  189. #endregion
  190. #region QueueWorkItem(Action<...>)
  191. public IWorkItemResult QueueWorkItem (Action action)
  192. {
  193. PreQueueWorkItem ();
  194. WorkItem workItem = WorkItemFactory.CreateWorkItem (
  195. this,
  196. WIGStartInfo,
  197. delegate
  198. {
  199. action.Invoke ();
  200. return null;
  201. });
  202. Enqueue (workItem);
  203. return workItem.GetWorkItemResult ();
  204. }
  205. public IWorkItemResult QueueWorkItem<T> (Action<T> action, T arg)
  206. {
  207. PreQueueWorkItem ();
  208. WorkItem workItem = WorkItemFactory.CreateWorkItem (
  209. this,
  210. WIGStartInfo,
  211. state =>
  212. {
  213. action.Invoke (arg);
  214. return null;
  215. },
  216. WIGStartInfo.FillStateWithArgs ? new object[] { arg } : null);
  217. Enqueue (workItem);
  218. return workItem.GetWorkItemResult ();
  219. }
  220. public IWorkItemResult QueueWorkItem<T1, T2> (Action<T1, T2> action, T1 arg1, T2 arg2)
  221. {
  222. PreQueueWorkItem ();
  223. WorkItem workItem = WorkItemFactory.CreateWorkItem (
  224. this,
  225. WIGStartInfo,
  226. state =>
  227. {
  228. action.Invoke (arg1, arg2);
  229. return null;
  230. },
  231. WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2 } : null);
  232. Enqueue (workItem);
  233. return workItem.GetWorkItemResult ();
  234. }
  235. public IWorkItemResult QueueWorkItem<T1, T2, T3> (Action<T1, T2, T3> action, T1 arg1, T2 arg2, T3 arg3)
  236. {
  237. PreQueueWorkItem ();
  238. WorkItem workItem = WorkItemFactory.CreateWorkItem (
  239. this,
  240. WIGStartInfo,
  241. state =>
  242. {
  243. action.Invoke (arg1, arg2, arg3);
  244. return null;
  245. },
  246. WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3 } : null);
  247. Enqueue (workItem);
  248. return workItem.GetWorkItemResult ();
  249. }
  250. public IWorkItemResult QueueWorkItem<T1, T2, T3, T4> (
  251. Action<T1, T2, T3, T4> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
  252. {
  253. PreQueueWorkItem ();
  254. WorkItem workItem = WorkItemFactory.CreateWorkItem (
  255. this,
  256. WIGStartInfo,
  257. state =>
  258. {
  259. action.Invoke (arg1, arg2, arg3, arg4);
  260. return null;
  261. },
  262. WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3, arg4 } : null);
  263. Enqueue (workItem);
  264. return workItem.GetWorkItemResult ();
  265. }
  266. #endregion
  267. #region QueueWorkItem(Func<...>)
  268. public IWorkItemResult<TResult> QueueWorkItem<TResult>(Func<TResult> func)
  269. {
  270. PreQueueWorkItem();
  271. WorkItem workItem = WorkItemFactory.CreateWorkItem(
  272. this,
  273. WIGStartInfo,
  274. state =>
  275. {
  276. return func.Invoke();
  277. });
  278. Enqueue(workItem);
  279. return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult());
  280. }
  281. public IWorkItemResult<TResult> QueueWorkItem<T, TResult>(Func<T, TResult> func, T arg)
  282. {
  283. PreQueueWorkItem();
  284. WorkItem workItem = WorkItemFactory.CreateWorkItem(
  285. this,
  286. WIGStartInfo,
  287. state =>
  288. {
  289. return func.Invoke(arg);
  290. },
  291. WIGStartInfo.FillStateWithArgs ? new object[] { arg } : null);
  292. Enqueue(workItem);
  293. return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult());
  294. }
  295. public IWorkItemResult<TResult> QueueWorkItem<T1, T2, TResult>(Func<T1, T2, TResult> func, T1 arg1, T2 arg2)
  296. {
  297. PreQueueWorkItem();
  298. WorkItem workItem = WorkItemFactory.CreateWorkItem(
  299. this,
  300. WIGStartInfo,
  301. state =>
  302. {
  303. return func.Invoke(arg1, arg2);
  304. },
  305. WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2 } : null);
  306. Enqueue(workItem);
  307. return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult());
  308. }
  309. public IWorkItemResult<TResult> QueueWorkItem<T1, T2, T3, TResult>(
  310. Func<T1, T2, T3, TResult> func, T1 arg1, T2 arg2, T3 arg3)
  311. {
  312. PreQueueWorkItem();
  313. WorkItem workItem = WorkItemFactory.CreateWorkItem(
  314. this,
  315. WIGStartInfo,
  316. state =>
  317. {
  318. return func.Invoke(arg1, arg2, arg3);
  319. },
  320. WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3 } : null);
  321. Enqueue(workItem);
  322. return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult());
  323. }
  324. public IWorkItemResult<TResult> QueueWorkItem<T1, T2, T3, T4, TResult>(
  325. Func<T1, T2, T3, T4, TResult> func, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
  326. {
  327. PreQueueWorkItem();
  328. WorkItem workItem = WorkItemFactory.CreateWorkItem(
  329. this,
  330. WIGStartInfo,
  331. state =>
  332. {
  333. return func.Invoke(arg1, arg2, arg3, arg4);
  334. },
  335. WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3, arg4 } : null);
  336. Enqueue(workItem);
  337. return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult());
  338. }
  339. #endregion
  340. #endregion
  341. }
  342. }