函数防抖(debounce):当频繁持续触发事件时,如果在设定时间间隔内重复触发事件,每次触发时间就重新开始计时,直至指定时间间隔内没有再触发事件,事件处理函数才会执行一次。
函数节流(throttle):当频繁持续触发事件时,保证每隔指定时间调用一次事件处理函数,指定间隔内只会调用一次。
debounce限制多长时间才能执行一次,throttle限制多长时间必须执行一次,一个限制上限、一个限制下限
函数防抖
1 using System; 2 using System.ComponentModel; 3 using System.Threading; 4 5 namespace Common 6 { 7 /// <summary> 8 /// 防抖活动--多次重复调用时,间隔固定时长不调用时执行一次 9 /// </summary> 10 public class DebounceAction 11 { 12 private Timer _timer; 13 private ISynchronizeInvoke _invoker; 14 private Action _action; 15 public TimeSpan Delay { get; private set; } 16 17 public DebounceAction(TimeSpan delay) 18 { 19 Delay = delay; 20 } 21 22 public DebounceAction(Action action, TimeSpan delay) : this(delay) 23 { 24 _action = action; 25 } 26 27 /// <summary> 28 /// 间隔固定时长不调用时执行一次 29 /// </summary> 30 public void Execute(ISynchronizeInvoke invoker = null) 31 { 32 Monitor.Enter(this); 33 bool needExit = true; 34 try 35 { 36 _invoker = invoker; 37 Cancel(); 38 _timer = new Timer(OnTimeTicked, null, (int)Delay.TotalMilliseconds, Timeout.Infinite); 39 Monitor.Exit(this); 40 needExit = false; 41 } 42 finally 43 { 44 if (needExit) 45 Monitor.Exit(this); 46 } 47 } 48 49 /// <summary> 50 /// 取消防抖操作 51 /// </summary> 52 public void Cancel() 53 { 54 if (_timer != null) 55 { 56 _timer.Dispose(); 57 _timer = null; 58 } 59 } 60 61 private void OnTimeTicked(object state) 62 { 63 Cancel(); 64 if (_action != null) 65 { 66 if (_invoker != null && _invoker.InvokeRequired) 67 { 68 _invoker.Invoke(_action, null); 69 } 70 else 71 { 72 _action.Invoke(); 73 } 74 } 75 } 76 } 77 }
函数节流
1 using System; 2 using System.ComponentModel; 3 using System.Threading; 4 5 namespace Common 6 { 7 /// <summary> 8 /// 节流活动--多次重复调用时,每间隔固定时长执行一次 9 /// </summary> 10 public class ThrottleAction 11 { 12 private Timer _timer; 13 private Action _action; 14 private ISynchronizeInvoke _invoker; 15 public TimeSpan Delay { get; private set; } 16 17 public ThrottleAction(TimeSpan delay) 18 { 19 Delay = delay; 20 } 21 22 public ThrottleAction(Action action, TimeSpan delay) 23 : this(delay) 24 { 25 _action = action; 26 } 27 28 /// <summary> 29 /// 每间隔固定时长执行一次 30 /// </summary> 31 /// <param name="invoker"></param> 32 public void Execute(ISynchronizeInvoke invoker = null) 33 { 34 Monitor.Enter(this); 35 bool needExit = true; 36 try 37 { 38 _invoker = invoker; 39 if (_timer == null) 40 { 41 _timer = new Timer(OnTimeTicked, null, (int)Delay.TotalMilliseconds, Timeout.Infinite); 42 Monitor.Exit(this); 43 needExit = false; 44 } 45 } 46 finally 47 { 48 if (needExit) 49 Monitor.Exit(this); 50 } 51 } 52 53 /// <summary> 54 /// 取消节流操作 55 /// </summary> 56 public void Cancel() 57 { 58 if (_timer != null) 59 { 60 _timer.Dispose(); 61 _timer = null; 62 } 63 } 64 65 private void OnTimeTicked(object state) 66 { 67 Cancel(); 68 if (_action != null) 69 { 70 if (_invoker != null && _invoker.InvokeRequired) 71 { 72 _invoker.Invoke(_action, null); 73 } 74 else 75 { 76 _action.Invoke(); 77 } 78 } 79 } 80 } 81 }