DebounceDispatcher.cs 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. /// <summary>
  8. /// 这个类提供了防抖和节流的功能
  9. /// </summary>
  10. public class DebounceDispatcher
  11. {
  12. System.Timers.Timer _timerDbc;
  13. System.Timers.Timer _timerTrt;
  14. /// <summary>
  15. /// 防抖,延迟timesMs后执行。 在此期间如果再次调用,则重新计时
  16. /// </summary>
  17. /// <param name="timeMs">间隔(毫秒)</param>
  18. /// <param name="action">回调函数</param>
  19. /// <param name="invoker">同步对象,一般为Control控件。 如不需同步可传null</param>
  20. public void Debounce(int timeMs, Action action, ISynchronizeInvoke invoker = null)
  21. {
  22. lock (this)
  23. {
  24. if (_timerDbc == null)
  25. {
  26. _timerDbc = new System.Timers.Timer(timeMs);
  27. _timerDbc.AutoReset = false;
  28. _timerDbc.Elapsed += (o, e) =>
  29. {
  30. _timerDbc.Stop();
  31. _timerDbc.Close();
  32. _timerDbc = null;
  33. InvokeAction(action, invoker);
  34. };
  35. }
  36. _timerDbc.Stop();
  37. _timerDbc.Start();
  38. }
  39. }
  40. /// <summary>
  41. /// 节流,即刻执行,执行之后,在timeMs内再次调用无效
  42. /// </summary>
  43. /// <param name="timeMs">不应期,这段时间内调用无效</param>
  44. /// <param name="action">回调函数</param>
  45. /// <param name="invoker">同步对象,一般为控件。 如不需同步可传null</param>
  46. public void Throttle(int timeMs, Action action, ISynchronizeInvoke invoker = null)
  47. {
  48. System.Threading.Monitor.Enter(this);
  49. bool needExit = true;
  50. try
  51. {
  52. if (_timerTrt == null)
  53. {
  54. _timerTrt = new System.Timers.Timer(timeMs);
  55. _timerTrt.AutoReset = false;
  56. _timerTrt.Elapsed += (o, e) =>
  57. {
  58. _timerTrt.Stop();
  59. _timerTrt.Close();
  60. _timerTrt = null;
  61. };
  62. _timerTrt.Start();
  63. System.Threading.Monitor.Exit(this);
  64. needExit = false;
  65. InvokeAction(action, invoker);//这个过程不能锁
  66. }
  67. }
  68. finally
  69. {
  70. if (needExit)
  71. System.Threading.Monitor.Exit(this);
  72. }
  73. }
  74. private static void InvokeAction(Action action, ISynchronizeInvoke invoker)
  75. {
  76. if (invoker == null)
  77. {
  78. action();
  79. }
  80. else
  81. {
  82. if (invoker.InvokeRequired)
  83. {
  84. invoker.Invoke(action, null);
  85. }
  86. else
  87. {
  88. action();
  89. }
  90. }
  91. }
  92. }