| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 | using System;using System.Collections.Generic;using System.ComponentModel;using System.Linq;using System.Text;using System.Threading.Tasks;/// <summary>/// 这个类提供了防抖和节流的功能/// </summary>public class DebounceDispatcher{    System.Timers.Timer _timerDbc;    System.Timers.Timer _timerTrt;    /// <summary>    /// 防抖,延迟timesMs后执行。 在此期间如果再次调用,则重新计时    /// </summary>    /// <param name="timeMs">间隔(毫秒)</param>    /// <param name="action">回调函数</param>    /// <param name="invoker">同步对象,一般为Control控件。 如不需同步可传null</param>    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();        }    }    /// <summary>    /// 节流,即刻执行,执行之后,在timeMs内再次调用无效    /// </summary>    /// <param name="timeMs">不应期,这段时间内调用无效</param>    /// <param name="action">回调函数</param>    /// <param name="invoker">同步对象,一般为控件。 如不需同步可传null</param>    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();            }        }    }}
 |