TimerComponent.cs 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. using System.Collections.Generic;
  2. using System.Threading;
  3. using System.Threading.Tasks;
  4. using Base;
  5. namespace Model
  6. {
  7. public class Timer
  8. {
  9. public long Id { get; set; }
  10. public long Time { get; set; }
  11. public TaskCompletionSource<bool> tcs;
  12. }
  13. [EntityEvent(typeof(TimerComponent))]
  14. public class TimerComponent: Component
  15. {
  16. private readonly Dictionary<long, Timer> timers = new Dictionary<long, Timer>();
  17. /// <summary>
  18. /// key: time, value: timer id
  19. /// </summary>
  20. private readonly MultiMap<long, long> timeId = new MultiMap<long, long>();
  21. private readonly Queue<long> timeoutTimer = new Queue<long>();
  22. public void Update()
  23. {
  24. long timeNow = TimeHelper.Now();
  25. foreach (long time in this.timeId.Keys)
  26. {
  27. if (time > timeNow)
  28. {
  29. break;
  30. }
  31. this.timeoutTimer.Enqueue(time);
  32. }
  33. while (this.timeoutTimer.Count > 0)
  34. {
  35. long key = this.timeoutTimer.Dequeue();
  36. long[] timeOutId = this.timeId.GetAll(key);
  37. foreach (long id in timeOutId)
  38. {
  39. Timer timer;
  40. if (!this.timers.TryGetValue(id, out timer))
  41. {
  42. continue;
  43. }
  44. this.Remove(id);
  45. timer.tcs.SetResult(true);
  46. }
  47. }
  48. }
  49. private void Remove(long id)
  50. {
  51. Timer timer;
  52. if (!this.timers.TryGetValue(id, out timer))
  53. {
  54. return;
  55. }
  56. this.timers.Remove(id);
  57. this.timeId.Remove(timer.Time, timer.Id);
  58. }
  59. public Task WaitTillAsync(long tillTime, CancellationToken cancellationToken)
  60. {
  61. TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
  62. Timer timer = new Timer { Id = IdGenerater.GenerateId(), Time = tillTime, tcs = tcs };
  63. this.timers[timer.Id] = timer;
  64. this.timeId.Add(timer.Time, timer.Id);
  65. cancellationToken.Register(() =>
  66. {
  67. this.Remove(timer.Id);
  68. });
  69. return tcs.Task;
  70. }
  71. public Task WaitTillAsync(long tillTime)
  72. {
  73. TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
  74. Timer timer = new Timer { Id = IdGenerater.GenerateId(), Time = tillTime, tcs = tcs };
  75. this.timers[timer.Id] = timer;
  76. this.timeId.Add(timer.Time, timer.Id);
  77. return tcs.Task;
  78. }
  79. public Task WaitAsync(long time, CancellationToken cancellationToken)
  80. {
  81. TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
  82. Timer timer = new Timer
  83. {
  84. Id = IdGenerater.GenerateId(),
  85. Time = TimeHelper.Now() + time,
  86. tcs = tcs
  87. };
  88. this.timers[timer.Id] = timer;
  89. this.timeId.Add(timer.Time, timer.Id);
  90. cancellationToken.Register(() =>
  91. {
  92. this.Remove(timer.Id);
  93. });
  94. return tcs.Task;
  95. }
  96. public Task WaitAsync(long time)
  97. {
  98. TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
  99. Timer timer = new Timer
  100. {
  101. Id = IdGenerater.GenerateId(),
  102. Time = TimeHelper.Now() + time,
  103. tcs = tcs
  104. };
  105. this.timers[timer.Id] = timer;
  106. this.timeId.Add(timer.Time, timer.Id);
  107. return tcs.Task;
  108. }
  109. }
  110. }