• C#.Net下的防抖Debounce和节流阀Throttle功能实现


    C#.Net下的防抖-Debounce和节流阀-Throttle功能实现

    C#下的防抖-Debounce、节流阀-Throttle功能实现

    防抖-Debounce

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

    节流阀-Throttle

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

    代码如下:

    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">不应期,这段时间内调用无效</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();
                    }
                }
            }
        }
    
    
  • 相关阅读:
    编程实践56
    诫子篇
    编程实践58
    编程实践55
    C#Process类应该声明个什么引用空间啊 找不到类型或命名空间名称“Process”(是否缺少 using 指令或程序集引用?) 如何解决?
    课堂题目54
    jQuery学习笔记jQuery的动画
    Asp.net生成各种网页快捷方式[转贴]
    jQuery学习笔记Helloworld
    FreeTextBox配置
  • 原文地址:https://www.cnblogs.com/grj001/p/12224732.html
Copyright © 2020-2023  润新知