ThreadPool.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. using SmartCoalApplication.SystemLayer;
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Threading;
  8. using System.Threading.Tasks;
  9. namespace SmartCoalApplication.Core.Threading
  10. {
  11. public class ThreadPool
  12. {
  13. private static ThreadPool global = new ThreadPool(2 * Processor.LogicalCpuCount);
  14. public static ThreadPool Global
  15. {
  16. get
  17. {
  18. return global;
  19. }
  20. }
  21. private ArrayList exceptions = ArrayList.Synchronized(new ArrayList());
  22. private bool useFXTheadPool;
  23. public static int MinimumCount
  24. {
  25. get
  26. {
  27. return WaitableCounter.MinimumCount;
  28. }
  29. }
  30. public static int MaximumCount
  31. {
  32. get
  33. {
  34. return WaitableCounter.MaximumCount;
  35. }
  36. }
  37. public Exception[] Exceptions
  38. {
  39. get
  40. {
  41. return (Exception[])this.exceptions.ToArray(typeof(Exception));
  42. }
  43. }
  44. public void ClearExceptions()
  45. {
  46. exceptions.Clear();
  47. }
  48. public void DrainExceptions()
  49. {
  50. if (this.exceptions.Count > 0)
  51. {
  52. throw new WorkerThreadException("Worker thread threw an exception", (Exception)this.exceptions[0]);
  53. }
  54. ClearExceptions();
  55. }
  56. private WaitableCounter counter;
  57. public ThreadPool()
  58. : this(Processor.LogicalCpuCount)
  59. {
  60. }
  61. public ThreadPool(int maxThreads)
  62. : this(maxThreads, true)
  63. {
  64. }
  65. public ThreadPool(int maxThreads, bool useFXThreadPool)
  66. {
  67. if (maxThreads < MinimumCount || maxThreads > MaximumCount)
  68. {
  69. throw new ArgumentOutOfRangeException("maxThreads", "must be between " + MinimumCount.ToString() + " and " + MaximumCount.ToString() + " inclusive");
  70. }
  71. this.counter = new WaitableCounter(maxThreads);
  72. this.useFXTheadPool = useFXThreadPool;
  73. }
  74. public void QueueUserWorkItem(WaitCallback callback)
  75. {
  76. QueueUserWorkItem(callback, null);
  77. }
  78. public void QueueUserWorkItem(WaitCallback callback, object state)
  79. {
  80. IDisposable token = counter.AcquireToken();
  81. ThreadWrapperContext twc = new ThreadWrapperContext(callback, state, token, this.exceptions);
  82. if (this.useFXTheadPool)
  83. {
  84. System.Threading.ThreadPool.QueueUserWorkItem(new WaitCallback(twc.ThreadWrapper), twc);
  85. }
  86. else
  87. {
  88. Thread thread = new Thread(new ThreadStart(twc.ThreadWrapper));
  89. thread.IsBackground = true;
  90. thread.Start();
  91. }
  92. }
  93. public bool IsDrained(uint msTimeout)
  94. {
  95. bool result = counter.IsEmpty(msTimeout);
  96. if (result)
  97. {
  98. Drain();
  99. }
  100. return result;
  101. }
  102. public bool IsDrained()
  103. {
  104. return IsDrained(0);
  105. }
  106. public void Drain()
  107. {
  108. counter.WaitForEmpty();
  109. DrainExceptions();
  110. }
  111. private sealed class ThreadWrapperContext
  112. {
  113. private WaitCallback callback;
  114. private object context;
  115. private IDisposable counterToken;
  116. private ArrayList exceptionsBucket;
  117. public ThreadWrapperContext(WaitCallback callback, object context,
  118. IDisposable counterToken, ArrayList exceptionsBucket)
  119. {
  120. this.callback = callback;
  121. this.context = context;
  122. this.counterToken = counterToken;
  123. this.exceptionsBucket = exceptionsBucket;
  124. }
  125. public void ThreadWrapper()
  126. {
  127. using (IDisposable token = this.counterToken)
  128. {
  129. try
  130. {
  131. this.callback(this.context);
  132. }
  133. catch (Exception ex)
  134. {
  135. this.exceptionsBucket.Add(ex);
  136. }
  137. }
  138. }
  139. public void ThreadWrapper(object state)
  140. {
  141. ThreadWrapper();
  142. }
  143. }
  144. }
  145. }