using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; /// /// 这个类提供了防抖和节流的功能 /// public class DebounceDispatcher { System.Timers.Timer _timerDbc; System.Timers.Timer _timerTrt; /// /// 防抖,延迟timesMs后执行。 在此期间如果再次调用,则重新计时 /// /// 间隔(毫秒) /// 回调函数 /// 同步对象,一般为Control控件。 如不需同步可传null public void Debounce(int timeMs, Action action, ISynchronizeInvoke invoker = null) { lock (this) { if (_timerDbc == null) { _timerDbc = new System.Timers.Timer(timeMs); _timerDbc.AutoReset = false; _timerDbc.Elapsed += (o, e) => { _timerDbc.Stop(); _timerDbc.Close(); _timerDbc = null; InvokeAction(action, invoker); }; } _timerDbc.Stop(); _timerDbc.Start(); } } /// /// 节流,即刻执行,执行之后,在timeMs内再次调用无效 /// /// 不应期,这段时间内调用无效 /// 回调函数 /// 同步对象,一般为控件。 如不需同步可传null public void Throttle(int timeMs, Action action, ISynchronizeInvoke invoker = null) { System.Threading.Monitor.Enter(this); bool needExit = true; try { if (_timerTrt == null) { _timerTrt = new System.Timers.Timer(timeMs); _timerTrt.AutoReset = false; _timerTrt.Elapsed += (o, e) => { _timerTrt.Stop(); _timerTrt.Close(); _timerTrt = null; }; _timerTrt.Start(); System.Threading.Monitor.Exit(this); needExit = false; InvokeAction(action, invoker);//这个过程不能锁 } } finally { if (needExit) System.Threading.Monitor.Exit(this); } } private static void InvokeAction(Action action, ISynchronizeInvoke invoker) { if (invoker == null) { action(); } else { if (invoker.InvokeRequired) { invoker.Invoke(action, null); } else { action(); } } } }