C# event debounce

后端 未结 14 1109
南旧
南旧 2020-11-28 06:22

I\'m listening to a hardware event message, but I need to debounce it to avoid too many queries.

This is an hardware event that sends the machine status and I have t

14条回答
  •  盖世英雄少女心
    2020-11-28 06:41

    I needed something like this but in a web-application, so I can't store the Action in a variable, it will be lost between http requests.

    Based on other answers and @Collie idea I created a class that looks at a unique string key for throttling.

    public static class Debouncer
    {
        static ConcurrentDictionary _tokens = new ConcurrentDictionary();
        public static void Debounce(string uniqueKey, Action action, int seconds)
        {
            var token = _tokens.AddOrUpdate(uniqueKey,
                (key) => //key not found - create new
                {
                    return new CancellationTokenSource();
                },
                (key, existingToken) => //key found - cancel task and recreate
                {
                    existingToken.Cancel(); //cancel previous
                    return new CancellationTokenSource();
                }
            );
    
            Task.Delay(seconds * 1000, token.Token).ContinueWith(task =>
            {
                if (!task.IsCanceled)
                {
                    action();
                    _tokens.TryRemove(uniqueKey, out _);
                }
            }, token.Token);
        }
    }
    

    Usage:

    //throttle for 5 secs if it's already been called with this KEY
    Debouncer.Debounce("Some-Unique-ID", () => SendEmails(), 5);
    

    As a side bonus, because it's based on a string key, you can use inline lambda's

    Debouncer.Debounce("Some-Unique-ID", () => 
    {
        //do some work here
    }, 5);
    

提交回复
热议问题