TimerManager.cs 1.9 KB

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