ThreadSchedulers.cs 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. using System;
  2. using System.Collections.Concurrent;
  3. namespace XGame.Framework.ThreadScheduler
  4. {
  5. /// <summary>
  6. /// 线程调度
  7. /// </summary>
  8. public static class ThreadSchedulers
  9. {
  10. private class TaskInfo
  11. {
  12. public Action<object> Action;
  13. public object Context;
  14. public void Clear()
  15. {
  16. Action = null;
  17. Context = null;
  18. }
  19. }
  20. private static ConcurrentQueue<TaskInfo> _queueTasks = new ConcurrentQueue<TaskInfo>();
  21. private static ConcurrentQueue<TaskInfo> _taskPool = new ConcurrentQueue<TaskInfo>();
  22. public static void RunOnMainThread(Action<object> action, object context)
  23. {
  24. var task = Get();
  25. task.Action = action;
  26. task.Context = context;
  27. _queueTasks.Enqueue(task);
  28. }
  29. private static void Recycle(TaskInfo task)
  30. {
  31. if (task != null)
  32. {
  33. task.Clear();
  34. _taskPool.Enqueue(task);
  35. }
  36. }
  37. private static TaskInfo Get()
  38. {
  39. if (!_taskPool.TryDequeue(out TaskInfo task))
  40. task = new TaskInfo();
  41. return task;
  42. }
  43. public static void Update()
  44. {
  45. while (_queueTasks.TryDequeue(out TaskInfo task))
  46. {
  47. if (task != default)
  48. {
  49. try
  50. {
  51. task.Action.Invoke(task.Context);
  52. }
  53. catch (Exception e)
  54. {
  55. if (e.InnerException != null)
  56. {
  57. Log.Error($"[ThreadSchedulers] Message: {e.InnerException.Message},\n" +
  58. $"StackTrace: {e.InnerException.StackTrace}");
  59. }
  60. else
  61. {
  62. Log.Error($"[ThreadSchedulers] Message: {e.Message} \n" +
  63. $"StackTrace: {e.StackTrace}");
  64. }
  65. }
  66. finally
  67. {
  68. Recycle(task);
  69. }
  70. }
  71. }
  72. }
  73. public static void Dispose()
  74. {
  75. while (_queueTasks.TryDequeue(out var task)) ;
  76. while (_taskPool.TryDequeue(out var task)) ;
  77. }
  78. }
  79. }