Worker.cs 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. using System;
  2. using System.Threading;
  3. using TBL.CSharp.Game.Server.Message;
  4. namespace TBL.CSharp.Game.Server.Process;
  5. /// <summary>
  6. /// 工作线程的封装
  7. /// </summary>
  8. public class Worker
  9. {
  10. /// <summary>
  11. /// 工作线程
  12. /// </summary>
  13. public readonly Thread WorkingThread;
  14. /// <summary>
  15. /// 工作线程应当继续运行
  16. /// </summary>
  17. private bool _threadShouldRunning;
  18. public unsafe Worker(ServiceContainer container)
  19. {
  20. _threadShouldRunning = true;
  21. WorkingThread = new Thread(() =>
  22. {
  23. SignalQueue queue;
  24. Signal signal;
  25. while (_threadShouldRunning)
  26. {
  27. OnLoopStart();
  28. // 从活跃服务队列中获取一个队列
  29. if (!container.ActiveSignalQueues.TryDequeue(out queue))
  30. {
  31. // 空队列的情况下节省 cpu 时间
  32. OnSignalQueueEmpty();
  33. continue;
  34. }
  35. // 对活跃队列加锁
  36. lock (queue)
  37. {
  38. // 队列已从活跃序列中移走
  39. queue.ActiveLock = false;
  40. // 队列中有消息
  41. if (queue.TryDequeue(out signal))
  42. {
  43. try
  44. {
  45. // 处理消息,此过程能保证线程安全
  46. queue.Owner.OnSignal(signal, container);
  47. }
  48. catch (Exception e)
  49. {
  50. // 异常处理
  51. OnServiceCallbackException(e);
  52. }
  53. // 如果信号携带数据,此时可以回收内存
  54. if (!signal.Data.IsNullPtr)
  55. signal.Data.Free();
  56. // 归还队列
  57. queue.ActiveLock = true;
  58. container.ActiveSignalQueues.Enqueue(queue);
  59. }
  60. }
  61. }
  62. // 终结流程
  63. OnTerminated();
  64. });
  65. }
  66. /// <summary>
  67. /// 停止
  68. /// </summary>
  69. public void RequestStop()
  70. {
  71. _threadShouldRunning = false;
  72. }
  73. /// <summary>
  74. /// 工作中
  75. /// </summary>
  76. public bool IsWorking => WorkingThread.IsAlive && _threadShouldRunning;
  77. /// <summary>
  78. /// 消息队列为空时触发
  79. /// <para>通常用于解脱 cpu 控制</para>
  80. /// </summary>
  81. public virtual void OnSignalQueueEmpty() => Thread.Yield();
  82. /// <summary>
  83. /// 服务回调异常时触发
  84. /// </summary>
  85. public virtual void OnServiceCallbackException(Exception e)
  86. {
  87. }
  88. /// <summary>
  89. /// 终结时触发
  90. /// </summary>
  91. public virtual void OnTerminated()
  92. {
  93. }
  94. /// <summary>
  95. /// 主循环一轮开始时触发
  96. /// </summary>
  97. public virtual void OnLoopStart()
  98. {
  99. }
  100. }