TimerManager.cs 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  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. public ObjectId Add(long time, Action action)
  21. {
  22. Timer timer = new Timer { Id = ObjectId.GenerateNewId(), Time = time, Action = action };
  23. this.timers[timer.Id] = timer;
  24. this.timeGuid.Add(timer.Time, timer.Id);
  25. return timer.Id;
  26. }
  27. public void Update(ObjectId id, long time)
  28. {
  29. Timer timer;
  30. if (!this.timers.TryGetValue(id, out timer))
  31. {
  32. return;
  33. }
  34. this.timeGuid.Remove(timer.Time, timer.Id);
  35. timer.Time = time;
  36. this.timeGuid.Add(timer.Time, timer.Id);
  37. }
  38. public void Remove(ObjectId id)
  39. {
  40. Timer timer;
  41. if (!this.timers.TryGetValue(id, out timer))
  42. {
  43. return;
  44. }
  45. this.timers.Remove(timer.Id);
  46. this.timeGuid.Remove(timer.Time, timer.Id);
  47. }
  48. public void Refresh()
  49. {
  50. long timeNow = TimeHelper.Now();
  51. var timeoutTimer = new List<long>();
  52. foreach (long time in this.timeGuid.Keys)
  53. {
  54. if (time > timeNow)
  55. {
  56. break;
  57. }
  58. timeoutTimer.Add(time);
  59. }
  60. foreach (long key in timeoutTimer)
  61. {
  62. ObjectId[] timeoutIds = this.timeGuid.GetAll(key);
  63. foreach (ObjectId id in timeoutIds)
  64. {
  65. Timer timer;
  66. if (!this.timers.TryGetValue(id, out timer))
  67. {
  68. continue;
  69. }
  70. this.Remove(id);
  71. timer.Action();
  72. }
  73. }
  74. }
  75. }
  76. }