The variant with await Task.Delay
is working, but it creates an extra timer and uses a pool of threads - while this particular task is quite simply solved without it.
This is how it is done using Stopwatch
:
private Stopwatch lastEvent; public void OnEvent() { if (lastEvent != null && lastEvent.ElapsedMilliseconds < 2000) return; lastEvent = Stopwatch.StartNew(); //... }
This can also be done with Environment.TickCount
- but there the code is a little more complicated; in addition, TickCount
loops after about 49 days of uptime (and a simple comparison begins to lie after 24 days).
I don’t recommend using DateTime.Now
for measuring time intervals - the user will transfer the system date and everything will hang.
PS If such an approach suddenly seems “not expressive enough” - you can make a service structure to enhance this very expressiveness:
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; } }
Now the main part of the code will be even more beautiful:
private DebounceHelper eventDebounceHelper = new DebounceHelper(TimeSpan.FromSeconds(2)); public void OnEvent() { if (!eventDebounceHelper.Test()) return; //... }