Last active
June 2, 2021 21:06
-
-
Save wgross/5b12c48420be6b2a93f4436220d33f8b to your computer and use it in GitHub Desktop.
Debounce and Throttle Event Handlers
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://www.meziantou.net/debouncing-throttling-javascript-events-in-a-blazor-application.htm | |
Action<T> Debounce<T>(Action<T> action, TimeSpan interval) | |
{ | |
if (action == null) throw new ArgumentNullException(nameof(action)); | |
var last = 0; | |
return arg => | |
{ | |
// increment while calls of the event are coming | |
var current = System.Threading.Interlocked.Increment(ref last); | |
// first incoming event starts the delayed invocation of the action | |
Task.Delay(interval).ContinueWith(task => | |
{ | |
// excute action after a period of time where no changes happen | |
if (current == last) | |
{ | |
action(arg); | |
} | |
}); | |
}; | |
} | |
Action<T> Throttle<T>(Action<T> action, TimeSpan interval) | |
{ | |
if (action == null) throw new ArgumentNullException(nameof(action)); | |
// captured in closure: | |
// .. the delivering delayed task | |
Task task = null; | |
// .. a lock handle | |
var l = new object(); | |
// .. a storage for the calling args | |
T args = default; | |
return (T arg) => | |
{ | |
// the latest calling args are kept for later use | |
args = arg; | |
// if the delayed delivery is already initialized, return | |
if (task != null) | |
return; | |
// starts the delayed deleivery task, once! | |
lock (l) | |
{ | |
// double locking... | |
if (task != null) | |
return; | |
// after exipry of the interval the latest args are delivered to the receiver | |
task = Task.Delay(interval).ContinueWith(t => | |
{ | |
action(args); | |
task = null; | |
}); | |
} | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment