ThreadPoolExecutor.cs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. using System;
  2. using System.Collections.Generic;
  3. using ST = System.Threading;
  4. namespace SharpCifs.Util.Sharpen
  5. {
  6. class ThreadPoolExecutor
  7. {
  8. ThreadFactory _tf;
  9. int _corePoolSize;
  10. int _maxPoolSize;
  11. List<Thread> _pool = new List<Thread> ();
  12. int _runningThreads;
  13. int _freeThreads;
  14. bool _shutdown;
  15. Queue<IRunnable> _pendingTasks = new Queue<IRunnable> ();
  16. public ThreadPoolExecutor (int corePoolSize, ThreadFactory factory)
  17. {
  18. this._corePoolSize = corePoolSize;
  19. _maxPoolSize = corePoolSize;
  20. _tf = factory;
  21. }
  22. public void SetMaximumPoolSize (int size)
  23. {
  24. _maxPoolSize = size;
  25. }
  26. public bool IsShutdown ()
  27. {
  28. return _shutdown;
  29. }
  30. public virtual bool IsTerminated ()
  31. {
  32. lock (_pendingTasks) {
  33. return _shutdown && _pendingTasks.Count == 0;
  34. }
  35. }
  36. public virtual bool IsTerminating ()
  37. {
  38. lock (_pendingTasks) {
  39. return _shutdown && !IsTerminated ();
  40. }
  41. }
  42. public int GetCorePoolSize ()
  43. {
  44. return _corePoolSize;
  45. }
  46. public void PrestartAllCoreThreads ()
  47. {
  48. lock (_pendingTasks) {
  49. while (_runningThreads < _corePoolSize)
  50. StartPoolThread ();
  51. }
  52. }
  53. public void SetThreadFactory (ThreadFactory f)
  54. {
  55. _tf = f;
  56. }
  57. public void Execute (IRunnable r)
  58. {
  59. InternalExecute (r, true);
  60. }
  61. internal void InternalExecute (IRunnable r, bool checkShutdown)
  62. {
  63. lock (_pendingTasks) {
  64. if (_shutdown && checkShutdown)
  65. throw new InvalidOperationException ();
  66. if (_runningThreads < _corePoolSize) {
  67. StartPoolThread ();
  68. }
  69. else if (_freeThreads > 0) {
  70. _freeThreads--;
  71. }
  72. else if (_runningThreads < _maxPoolSize) {
  73. StartPoolThread ();
  74. }
  75. _pendingTasks.Enqueue (r);
  76. ST.Monitor.PulseAll (_pendingTasks);
  77. }
  78. }
  79. void StartPoolThread ()
  80. {
  81. _runningThreads++;
  82. _pool.Add (_tf.NewThread (new RunnableAction (RunPoolThread)));
  83. }
  84. public void RunPoolThread ()
  85. {
  86. while (!IsTerminated ()) {
  87. try {
  88. IRunnable r = null;
  89. lock (_pendingTasks) {
  90. _freeThreads++;
  91. while (!IsTerminated () && _pendingTasks.Count == 0)
  92. ST.Monitor.Wait (_pendingTasks);
  93. if (IsTerminated ())
  94. break;
  95. r = _pendingTasks.Dequeue ();
  96. }
  97. if (r != null)
  98. r.Run ();
  99. }
  100. //supress all errors, anyway
  101. //catch (ST.ThreadAbortException) {
  102. // // Do not catch a thread abort. If we've been aborted just let the thread die.
  103. // // Currently reseting an abort which was issued because the appdomain is being
  104. // // torn down results in the process living forever and consuming 100% cpu time.
  105. // return;
  106. //}
  107. catch {
  108. }
  109. }
  110. }
  111. public virtual void Shutdown ()
  112. {
  113. lock (_pendingTasks) {
  114. _shutdown = true;
  115. ST.Monitor.PulseAll (_pendingTasks);
  116. }
  117. }
  118. public virtual List<IRunnable> ShutdownNow ()
  119. {
  120. lock (_pendingTasks) {
  121. _shutdown = true;
  122. foreach (var t in _pool) {
  123. try {
  124. t.Abort ();
  125. } catch {}
  126. }
  127. _pool.Clear ();
  128. _freeThreads = 0;
  129. _runningThreads = 0;
  130. var res = new List<IRunnable> (_pendingTasks);
  131. _pendingTasks.Clear ();
  132. return res;
  133. }
  134. }
  135. }
  136. class RunnableAction: IRunnable
  137. {
  138. Action _action;
  139. public RunnableAction (Action a)
  140. {
  141. _action = a;
  142. }
  143. public void Run ()
  144. {
  145. _action ();
  146. }
  147. }
  148. }