使方法延迟一段时间再执行

功能A:开启一个定时器,定时间隔到达后,执行一次后停用这个定时器。
功能A能够重复使用。

using System;

namespace DelayActionDemo
{
    public class TimeInvokeMethod : IDisposable
    {
        private int _timeOut = 100;

        private Delegate _action;

        private object[] _params;

        private System.Timers.Timer _timer;

        //private SynchronizationContext _dispatcher;

        public TimeInvokeMethod After(int milliseconds)
        {
            _timeOut = milliseconds;
            return this;
        }


        public TimeInvokeMethod SetAction(Delegate action, params object[] param)
        {
            _timer?.Stop();
            _action = action;
            _params = param;
            return this;
        }

        public TimeInvokeMethod SetAction(Action action)
        {
            _timer?.Stop();
            _action = action;
            _params = null;
            return this;
        }

        public TimeInvokeMethod SetAction<T>(Action<T> action, T param)
        {
            _timer?.Stop();
            _action = action;
            _params = new object[1] { param };
            return this;
        }

        public TimeInvokeMethod SetAction<T1, T2>(Action<T1, T2> action, T1 param1, T2 param2)
        {
            _timer?.Stop();
            _action = action;
            _params = new object[2] { param1, param2 };
            return this;
        }

        //public TimeInvokeMethod OnThread(SynchronizationContext dispatcher)
        //{
        //    _dispatcher = dispatcher;
        //    return this;
        //}

        public TimeInvokeMethod Go()
        {
            if (_timeOut <= 0)
            {
                _timer?.Stop();
                Invoke();
                return this;
            }
            if (_timer == null)
            {
                _timer = new System.Timers.Timer();
                _timer.Elapsed += TimerOnTick;
                _timer.Interval = _timeOut;
                _timer.Start();
                return this;
            }
            _timer.Stop();
            _timer.Interval = _timeOut;
            _timer.Start();
            return this;
        }

        private void TimerOnTick(object sender, EventArgs e)
        {
            _timer.Stop();
            Invoke();
        }

        public void Dispose()
        {
            if (_timer != null)
            {
                _timer.Stop();
                _timer.Elapsed -= TimerOnTick;
                _timer = null;
            }
            _action = null;
            //_dispatcher = null;
        }

        private void Invoke()
        {
            if ((object)_action == null)
            {
                return;
            }
            _action.DynamicInvoke(_params);
            //if (_dispatcher == null)
            //{
            //    _action.DynamicInvoke(_params);
            //}
            //else
            //{
            //    _dispatcher.Send(_ =>
            //    {
            //        _action.DynamicInvoke(_params);
            //    }, _params);
            //}
        }

    }
}

使用示例:

private void runBtn_Click(object sender, RoutedEventArgs e)
{
    Log(runBtn.Content.ToString());
    //this.RestartTimer(SECONDS);
    var context = SynchronizationContext.Current;
    //var hhh = context.GetHashCode();
    Task.Run(() => 
    {
        var ccc=SynchronizationContext.Current;
        scanScodeEndMethod.SetAction(StopScan, "停止").After(5000).Go();
    });
}

private void StopScan(string param)
{
    Log(param);
}

效果:
延迟一段时间后再执行
Over!!!
从上面效果可以看出,在超时时间内,多次调用Go方法,目标方法只会执行一次!
联想场景1 防抖:设置一个200ms的延时 如果用户在200ms内多击了按钮,则只会响应一次点击。
联想场景2 搜索:设置一个50ms的延时用在搜索框上,用户在50ms内敲了多个字母,则只会向服务器发送一次检索请求 (请求内容是这个时间内输入的所有字符)。
联想场景3 锁屏:设置一个60*1000ms的超时时间 用户在此时间内如果有操作则再次调用Go()方法重置超时判断,用户若超出此时间无任何操作则触发超时判断。

posted @ 2024-08-28 01:03  BigBosscyb  阅读(11)  评论(0)    收藏  举报