防抖 - Debounce

连续的多次调用,只有在调用停止之后的一段时间内不再调用,然后才执行一次处理过程。

节流阀 - Throttle

连续的多次调用,在每个时间段的周期内只执行第一次处理过程。

代码如下:

p
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Timers;
using System.Threading.Tasks;
using System.ComponentModel;
 
namespace HZ.Common
{
    public class DelayAction
    {
        Timer _timerDbc;
        Timer _timerTrt;
 
        /// <summary>
        /// 延迟 timesMs 后执行。 在此期间如果再次调用,则重新计时
        /// </summary>
        /// <param name="invoker"> 同步对象,一般为 Control 控件。 如不需同步可传 null</param>
        public void Debounce(int timeMs, ISynchronizeInvoke invoker, Action action)
        {
            lock (this)
            {
                if (_timerDbc == null)
                {
                    _timerDbc = new 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"> 不应期,这段时间内调用无效 & lt;/param>
        /// <param name="invoker"> 同步对象,一般为控件。 如不需同步可传 null</param>
        public void Throttle(int timeMs, ISynchronizeInvoke invoker, Action action)
        {
            System.Threading.Monitor.Enter(this);
            bool needExit = true;
            try
            {
                if (_timerTrt == null)
                {
                    _timerTrt = new 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);
            }
        }
 
        /// <summary>
        /// 延迟 timesMs 后执行。
        /// </summary>
        public void Delay(int timeMs, ISynchronizeInvoke invoker, Action action)
        {
            Debounce(timeMs, invoker, action);
        }
 
        private static void InvokeAction(Action action, ISynchronizeInvoke invoker)
        {
            if (invoker == null)
            {
                action();
            }
            else
            {
                if (invoker.InvokeRequired)
                {
                    invoker.Invoke(action, null);
                }
                else
                {
                    action();
                }
            }
        }
    }
}
更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

Roc 微信支付

微信支付

Roc 支付宝

支付宝