CTask.cs 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Runtime.CompilerServices;
  4. using System.Runtime.ExceptionServices;
  5. using System.Threading.Tasks;
  6. using Fort23.UTool;
  7. namespace Fort23.Core
  8. {
  9. public enum AwaiterStatus
  10. {
  11. Pending,
  12. Succeeded,
  13. Faulted,
  14. }
  15. /// <summary>
  16. /// 这是一个同步等待异步的框架, 如果要使用真正的异步,请使用Task
  17. /// A
  18. /// </summary>
  19. [AsyncMethodBuilder(typeof(AsyncTaskMethodBuilder))]
  20. public class CTask : ICTaskResult, IAwaitable<CTask>, IAwaiter
  21. {
  22. private Action _continuation;
  23. private AwaiterStatus state;
  24. private Exception _exception;
  25. private static readonly Queue<CTask> queue = new Queue<CTask>();
  26. public int currIndex = 0;
  27. static int allIndex = 0;
  28. public static bool isHindPool=false;
  29. /// <summary>
  30. /// 创建 <see cref="CTask{T}"/> 的新实例,并得到一个可以用于报告操作执行完毕的委托。
  31. /// </summary>
  32. /// <returns>
  33. /// 创建好的 <see cref="CTask{T}"/> 的新实例,将此返回值作为方法的返回值可以让方法支持 await 异步等待。
  34. /// </returns>
  35. public static CTask Create(bool isPool=true)
  36. {
  37. #if !COMBAT_SERVER
  38. lock (queue)
  39. {
  40. if (queue.Count == 0||!isPool||isHindPool)
  41. {
  42. CTask cTask = new CTask();
  43. allIndex++;
  44. cTask.currIndex = allIndex;
  45. return cTask;
  46. }
  47. CTask value = queue.Dequeue();
  48. value.state = AwaiterStatus.Pending;
  49. return value;
  50. }
  51. #endif
  52. return new CTask();
  53. // var task = new CTask();
  54. // return task;
  55. }
  56. private CTask()
  57. {
  58. }
  59. public CTask GetAwaiter()
  60. {
  61. return this;
  62. }
  63. public bool IsCompleted
  64. {
  65. get { return this.state != AwaiterStatus.Pending; }
  66. }
  67. public void OnCompleted(Action continuation)
  68. {
  69. if (IsCompleted)
  70. {
  71. continuation?.Invoke();
  72. }
  73. else
  74. {
  75. _continuation += continuation;
  76. }
  77. }
  78. // private T Result { get; set; }
  79. /// <summary>
  80. /// 这个方法在return await CTask的时候自动调用
  81. /// </summary>
  82. public void GetResult()
  83. {
  84. if (_exception != null)
  85. {
  86. ExceptionDispatchInfo.Capture(_exception).Throw();
  87. }
  88. Recycle();
  89. }
  90. /// <summary>
  91. /// 调用此方法以报告任务结束,并指定返回值和异步任务中的异常。
  92. /// 当使用 <see cref="Create"/> 静态方法创建此类型的实例后,调用方可以通过方法参数中传出的委托来调用此方法。
  93. /// </summary>
  94. /// <param name="exception">异步操作中的异常。</param>
  95. public void SetResult(Exception exception = null)
  96. {
  97. _exception = exception;
  98. if (AwaiterStatus.Faulted == state)
  99. {
  100. return;
  101. }
  102. this.state = AwaiterStatus.Succeeded;
  103. if (_continuation != null)
  104. {
  105. _continuation.Invoke();
  106. }
  107. }
  108. public void SetResult()
  109. {
  110. SetResult(null);
  111. }
  112. /// <summary>
  113. ///
  114. /// </summary>
  115. /// <param name="exception"></param>
  116. public void SetException(Exception exception)
  117. {
  118. this.state = AwaiterStatus.Faulted;
  119. _exception = exception;
  120. LogTool.Error(_exception);
  121. }
  122. private void Recycle()
  123. {
  124. _continuation = null;
  125. _exception = null;
  126. if (state == AwaiterStatus.Pending)
  127. {
  128. return;
  129. }
  130. this.state = AwaiterStatus.Pending;
  131. #if !COMBAT_SERVER
  132. lock (queue)
  133. {
  134. // 太多了
  135. if (queue.Count > 300||isHindPool)
  136. {
  137. return;
  138. }
  139. if (queue.Contains(this))
  140. {
  141. return;
  142. }
  143. queue.Enqueue(this);
  144. }
  145. #endif
  146. }
  147. public override async Task AwaitTask()
  148. {
  149. await this;
  150. }
  151. }
  152. /// <summary>
  153. /// 这是一个同步等待异步的框架, 如果要使用真正的异步,请使用Task
  154. /// A
  155. /// </summary>
  156. /// <typeparam name="T"></typeparam>
  157. [AsyncMethodBuilder(typeof(AsyncTaskMethodBuilder<>))]
  158. public class CTask<T> : ICTaskResult, IAwaitable<CTask<T>, T>, IAwaiter<T>
  159. {
  160. private Action _continuation;
  161. private AwaiterStatus state;
  162. private Exception _exception;
  163. #if !COMBAT_SERVER
  164. private static readonly Queue<CTask<T>> queue = new Queue<CTask<T>>();
  165. #endif
  166. public static bool isHindPool=false;
  167. /// <summary>
  168. /// 创建 <see cref="CTask{T}"/> 的新实例,并得到一个可以用于报告操作执行完毕的委托。
  169. /// </summary>
  170. /// <returns>
  171. /// 创建好的 <see cref="CTask{T}"/> 的新实例,将此返回值作为方法的返回值可以让方法支持 await 异步等待。
  172. /// </returns>
  173. public static CTask<T> Create(bool isPool=true)
  174. {
  175. #if !COMBAT_SERVER
  176. lock (queue)
  177. {
  178. if (queue.Count == 0||!isPool||isHindPool)
  179. {
  180. return new CTask<T>();
  181. }
  182. CTask<T> value = queue.Dequeue();
  183. value.state = AwaiterStatus.Pending;
  184. return value;
  185. }
  186. #endif
  187. return new CTask<T>();
  188. // var task = new CTask<T>();
  189. // return task;
  190. }
  191. private CTask()
  192. {
  193. }
  194. public CTask<T> GetAwaiter()
  195. {
  196. return this;
  197. }
  198. public bool IsCompleted
  199. {
  200. get { return state != AwaiterStatus.Pending; }
  201. }
  202. public void OnCompleted(Action continuation)
  203. {
  204. if (IsCompleted)
  205. {
  206. continuation?.Invoke();
  207. }
  208. else
  209. {
  210. _continuation += continuation;
  211. }
  212. }
  213. private T _result;
  214. public T Result
  215. {
  216. get { return _result; }
  217. }
  218. /// <summary>
  219. /// 这个方法在return await CTask的时候自动调用
  220. /// </summary>
  221. /// <returns></returns>
  222. public T GetResult()
  223. {
  224. if (_exception != null)
  225. {
  226. ExceptionDispatchInfo.Capture(_exception).Throw();
  227. }
  228. Recycle();
  229. return _result;
  230. }
  231. /// <summary>
  232. /// 调用此方法以报告任务结束,并指定返回值和异步任务中的异常。
  233. /// 当使用 <see cref="Create"/> 静态方法创建此类型的实例后,调用方可以通过方法参数中传出的委托来调用此方法。
  234. /// </summary>
  235. /// <param name="result">异步返回值。</param>
  236. /// <param name="exception">异步操作中的异常。</param>
  237. public void SetResult(T result, Exception exception = null)
  238. {
  239. _result = result;
  240. _exception = exception;
  241. if (this.state == AwaiterStatus.Faulted)
  242. {
  243. return;
  244. }
  245. this.state = AwaiterStatus.Succeeded;
  246. if (_continuation != null)
  247. {
  248. _continuation.Invoke();
  249. }
  250. }
  251. /// <summary>
  252. ///
  253. /// </summary>
  254. /// <param name="exception"></param>
  255. public void SetException(Exception exception)
  256. {
  257. this.state = AwaiterStatus.Faulted;
  258. _exception = exception;
  259. LogTool.Error(_exception);
  260. }
  261. private void Recycle()
  262. {
  263. _continuation = null;
  264. _exception = null;
  265. if (state == AwaiterStatus.Pending)
  266. {
  267. return;
  268. }
  269. this.state = AwaiterStatus.Pending;
  270. #if !COMBAT_SERVER
  271. lock (queue)
  272. {
  273. // 太多了,回收一下
  274. if (queue.Count > 300||isHindPool)
  275. {
  276. return;
  277. }
  278. if (queue.Contains(this))
  279. {
  280. return;
  281. }
  282. queue.Enqueue(this);
  283. }
  284. #endif
  285. }
  286. public override async Task AwaitTask()
  287. {
  288. await this;
  289. }
  290. }
  291. }