TimerComponent.cs 2.8 KB

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