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
This little gem is inspired by Mike Wards diabolically ingenious extension attempt. However, this one cleans up after itself quite nicely.
public static Action Debounce(this Action action, int milliseconds = 300)
{
CancellationTokenSource lastCToken = null;
return () =>
{
//Cancel/dispose previous
lastCToken?.Cancel();
try {
lastCToken?.Dispose();
} catch {}
var tokenSrc = lastCToken = new CancellationTokenSource();
Task.Delay(milliseconds).ContinueWith(task => { action(); }, tokenSrc.Token);
};
}
Note: there's no need to dispose of the task in this case. See here for the evidence.
Usage
Action DebounceToConsole;
int count = 0;
void Main()
{
//Assign
DebounceToConsole = ((Action)ToConsole).Debounce(50);
var random = new Random();
for (int i = 0; i < 50; i++)
{
DebounceToConsole();
Thread.Sleep(random.Next(100));
}
}
public void ToConsole()
{
Console.WriteLine($"I ran for the {++count} time.");
}