TimerManager.cs 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. using System;
  2. using System.Collections.Generic;
  3. namespace Base
  4. {
  5. public class TimerManager
  6. {
  7. private class Timer
  8. {
  9. public long Id { get; set; }
  10. public long Time { get; set; }
  11. public Action Action { get; set; }
  12. }
  13. private readonly Dictionary<long, Timer> timers = new Dictionary<long, Timer>();
  14. /// <summary>
  15. /// key: time, value: timer id
  16. /// </summary>
  17. private readonly MultiMap<long, long> timeGuid = new MultiMap<long, long>();
  18. private readonly Queue<long> timeoutTimer = new Queue<long>();
  19. public long Add(long time, Action action)
  20. {
  21. Timer timer = new Timer { Id = IdGenerater.GenerateId(), Time = time, Action = action };
  22. this.timers[timer.Id] = timer;
  23. this.timeGuid.Add(timer.Time, timer.Id);
  24. return timer.Id;
  25. }
  26. public void Remove(long id)
  27. {
  28. Timer timer;
  29. if (!this.timers.TryGetValue(id, out timer))
  30. {
  31. return;
  32. }
  33. this.timers.Remove(timer.Id);
  34. this.timeGuid.Remove(timer.Time, timer.Id);
  35. }
  36. public void Update()
  37. {
  38. long timeNow = TimeHelper.ClientNow();
  39. foreach (long time in this.timeGuid.Keys)
  40. {
  41. if (time > timeNow)
  42. {
  43. break;
  44. }
  45. this.timeoutTimer.Enqueue(time);
  46. }
  47. while (this.timeoutTimer.Count > 0)
  48. {
  49. long key = this.timeoutTimer.Dequeue();
  50. long[] timeoutIds = this.timeGuid.GetAll(key);
  51. foreach (long id in timeoutIds)
  52. {
  53. Timer timer;
  54. if (!this.timers.TryGetValue(id, out timer))
  55. {
  56. continue;
  57. }
  58. this.Remove(id);
  59. timer.Action();
  60. }
  61. }
  62. }
  63. }
  64. }