Страницы

Поиск по вопросам

среда, 4 декабря 2019 г.

Анти дребезг срабатывания события в C#

#c_sharp


Доброго времени суток. Интересует как реализовать срабатывания события не чаше чем
например 2 сек. т.е. человек долбит по кнопке, на кнопку подписано событие, нужно чтобы
при срабатывании события запускался какой то таймер отсчитывал интервал времени в течении
которого событие не сработает. Вроде задача не сложная а с таймером получается много
кода (запуск, проверка условия, сброс таймера). может это организовывается на async/await?

Заранее всем спасибо!!
    


Ответы

Ответ 1



Проще простого. bool isClickHot = false; void OnClick(...) { if (isClickHot) return; BlockClick(); // ваш обработчик } async void BlockClick() { isClickHot = true; await Task.Delay(2000); isClickHot = false; }

Ответ 2



Вариант с await Task.Delay - рабочий, но он создает лишний таймер и использует пул потоков - в то время как именно эта задача довольно просто решается без него. Вот так это делается с использованием Stopwatch: private Stopwatch lastEvent; public void OnEvent() { if (lastEvent != null && lastEvent.ElapsedMilliseconds < 2000) return; lastEvent = Stopwatch.StartNew(); //... } Еще это можно сделать с помощью Environment.TickCount - но там код получается чуть сложнее; кроме того, TickCount зацикливается после примерно 49 дней аптайма (а простое сравнение начинает врать через 24 дня). Использовать же DateTime.Now для измерения промежутков времени я не рекомендую - пользователь переведет системную дату и все повиснет. PS Если такой подход вдруг кажется "недостаточно выразительным" - можно сделать служебную структурку для повышения этой самой выразительности: public struct DebounceHelper { private TimeSpan delay; private Stopwatch lastEvent; public DebounceHelper(TimeSpan delay) { this.delay = delay; this.lastEvent = null; } public bool Test() { if (lastEvent != null && lastEvent.Elapsed < delay) return false; lastEvent = Stopwatch.StartNew(); return true; } } Теперь основная часть кода окажется еще более красивой: private DebounceHelper eventDebounceHelper = new DebounceHelper(TimeSpan.FromSeconds(2)); public void OnEvent() { if (!eventDebounceHelper.Test()) return; //... }

Комментариев нет:

Отправить комментарий