首页 > 解决方案 > 如何停止在 5 秒内多次调用方法?

问题描述

我有这个方法:

    public static async Task OpenPageAsync(string route)
    {
        await Shell.Current.GoToAsync(route, true);
    }

如果在 5 秒内多次调用该方法,我希望忽略第二次调用。有没有人遇到过处理这种需求的方法?

请注意,如果它有帮助,我确实可以像这样在应用程序级别创建属性等。

public partial class App : Application
{
    public static int LastTapTime;
    public static int TapTime;

标签: c#

解决方案


在我们的项目中,我们为此创建了一个“MaxFrequencyUpdater”。唯一的区别:如果在 5 秒内有新呼叫进来,它会延迟并在 5 秒间隔后执行。

namespace Utils
{
    public class MaxFrequencyUpdater
    {
        private readonly WinformsExceptionHandler _exceptionHandler;

        private readonly string _name;
        private readonly int _millis;
        private MethodInvoker _currentMethod;
        private DateTime _lastExecuted = DateTime.MinValue;
        private readonly object _updaterLockObject = new object();

        public MaxFrequencyUpdater(string name, int maxFrequencyInMillis, WinformsExceptionHandler exceptionHandler)
        {
            _name = name;
            _exceptionHandler = exceptionHandler;
            _millis = maxFrequencyInMillis;
        }
        
        public void Update(MethodInvoker method)
        {
            lock (_updaterLockObject)
            {
                _currentMethod = method;
            }
            Task.Run(HandleWork);
        }

        private void HandleWork()
        {
            lock (_updaterLockObject)
            {
                // No longer bother, someone else handled it already
                if (_currentMethod == null) return;

                var now = DateTime.Now;
                var delay = (int)(_millis - now.Subtract(_lastExecuted).TotalMilliseconds);

                // Post-pone if too soon
                if (delay > 0)
                {
                    Task.Delay(delay).ContinueWith(HandleWork);
                }
                else
                {
                    try
                    {
                        _currentMethod.Invoke();
                    }
                    catch (Exception e)
                    {
                        _exceptionHandler.HandleException(e);
                    }

                    _lastExecuted = now;
                    _currentMethod = null;
                }
            }
        }
    }
}

用法:

_maxFrequencyUpdater.Update(() =>
        {
            doSomething();
        });

推荐阅读