ThrottleDebounce 2.0.0-SNAPSHOT
See the version list below for details.
dotnet add package ThrottleDebounce --version 2.0.0-SNAPSHOT
NuGet\Install-Package ThrottleDebounce -Version 2.0.0-SNAPSHOT
<PackageReference Include="ThrottleDebounce" Version="2.0.0-SNAPSHOT" />
paket add ThrottleDebounce --version 2.0.0-SNAPSHOT
#r "nuget: ThrottleDebounce, 2.0.0-SNAPSHOT"
// Install ThrottleDebounce as a Cake Addin #addin nuget:?package=ThrottleDebounce&version=2.0.0-SNAPSHOT&prerelease // Install ThrottleDebounce as a Cake Tool #tool nuget:?package=ThrottleDebounce&version=2.0.0-SNAPSHOT&prerelease
ThrottleDebounce
Rate limit your actions and funcs by throttling and debouncing them.
This is a .NET library that lets you rate-limit functions so they are only executed at most once in a given interval, even if they are invoked multiple times in that interval.
Installation
This package is available on NuGet Gallery.
Install-Package ThrottleDebounce
dotnet add package ThrottleDebounce
It targets .NET Standard 2.0 and .NET Framework 4.0, so it should be compatible with many runtimes.
Usage
Action originalAction;
Func<int> originalFunc;
TimeSpan wait = TimeSpan.FromMilliseconds(50);
using RateLimitedAction throttledAction = Throttler.Throttle(originalAction, wait, leading: true, trailing: true);
using RateLimitedFunc<int> debouncedFunc = Debouncer.Debounce(originalFunc, wait, leading: false, trailing: true);
throttledAction.Invoke();
int? result = debouncedFunc.Invoke();
- Call
Throttler.Throttle()
to throttle your delegate, orDebouncer.Debounce()
to debounce it. PassAction action
/Func func
— your delegate to rate-limitTimeSpan wait
— how long to wait between executionsbool leading
—true
if the first invocation should be executed immediately, orfalse
if it should be queued. Optional, defaults totrue
for throttling andfalse
for debouncing.bool trailing
—true
if subsequent invocations in the waiting period should be enqueued for later execution once the waiting interval is over, orfalse
if they should be discarded. Optional, defaults totrue
.
- Call the resulting
RateLimitedAction
/RateLimitedFunc
object'sInvoke()
method to enqueue an invocation.RateLimitedFunc.Invoke
will returndefault
(e.g.null
) ifleading
isfalse
and the rate-limitedFunc
has not been executed before. Otherwise, it will return theFunc
's most recent return value.
- Your delegate will be executed at the desired rate.
- Optionally call the
RateLimitedAction
/RateLimitedFunc
object'sDispose()
method to prevent all queued executions from running when you are done.
Understanding throttling and debouncing
Summary
Throttling and debouncing both restrict a function to not execute too often, no matter how frequently you invoke it.
This is useful if the function is invoked very frequently, like whenever the mouse moves, but you don't want to it to run every single time the pointer moves 1 pixel, because the function is expensive, such as rendering a user interface.
Throttling allows the function to still be executed periodically, even with a constant stream of invocations.
Debouncing prevents the function from being executed at all until it hasn't been invoked for a while.
An invocation can result in at most one execution. For example, if both leading
and trailing
are true
, one single invocation will execute once on the leading edge and not on the trailing edge.
Diagram
Lodash documentation
Article and demo
Debouncing and Throttling Explained Through Examples by David Corbacho
Examples
Throttle an action to execute at most every 1 second
Action throttled = Throttler.Throttle(() => Console.WriteLine("hi"), TimeSpan.FromSeconds(1)).Invoke;
throttled(); //logs at 0s
throttled(); //logs at 1s
Thread.Sleep(1000);
throttled(); //logs at 2s
Debounce a function to execute after no invocations for 200 milliseconds
Func<double, double, double> debounced = Debouncer.Debounce((double x, double y) => Math.Sqrt(x * x + y * y),
TimeSpan.FromMilliseconds(200)).Invoke;
double? result;
result = debounced(1, 1); //never runs
result = debounced(2, 2); //never runs
result = debounced(3, 4); //runs at 200ms
Canceling a rate-limited action so any queued executions won't run
RateLimitedAction rateLimited = Throttler.Throttle(() => Console.WriteLine("hello"), TimeSpan.FromSeconds(1));
rateLimited.Invoke(); //runs at 0s
rateLimited.Dispose();
rateLimited.Invoke(); //never runs
Save a WPF window's position to the registry at most every 1 second
static void SaveWindowLocation(double x, double y) => Registry.SetValue(@"HKEY_CURRENT_USER\Software\My Program",
"Window Location", $"{x},{y}");
Action<double, double> saveWindowLocationThrottled = Throttler.Throttle<double, double>(saveWindowLocation,
TimeSpan.FromSeconds(1)).Invoke;
LocationChanged += (sender, args) => SaveWindowLocationThrottled(Left, Top);
Prevent accidental double-clicks on a WPF button
public MainWindow(){
InitializeComponent();
Action<object, RoutedEventArgs> onButtonClickDebounced = Debouncer.Debounce<object, RoutedEventArgs>(
OnButtonClick, TimeSpan.FromMilliseconds(40), true, false).Invoke;
MyButton.Click += new RoutedEventHandler(onButtonClickDebounced);
}
private void OnButtonClick(object sender, RoutedEventArgs e) {
MessageBox.Show("Button clicked");
}
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net40 is compatible. net403 was computed. net45 was computed. net451 was computed. net452 was computed. net46 was computed. net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.0
- No dependencies.
-
.NETStandard 2.0
- No dependencies.
NuGet packages (51)
Showing the top 5 NuGet packages that depend on ThrottleDebounce:
Package | Downloads |
---|---|
Elsa
Bundles the most commonly-used packages when building an Elsa workflows application. |
|
Elsa.Workflows.Runtime
Provides workflow runtime functionality. |
|
Elsa.Retention
Provides retention options for workflows. |
|
Elsa.EntityFrameworkCore
Provides Entity Framework Core implementations of various abstractions from various modules. |
|
Elsa.Http
Provides HTTP activities to listen for and send out HTTP requests. |
GitHub repositories (2)
Showing the top 2 popular GitHub repositories that depend on ThrottleDebounce:
Repository | Stars |
---|---|
elsa-workflows/elsa-core
A .NET workflows library
|
|
elsa-workflows/elsa-studio
A modular, extensible dashboard application framework
|
Version | Downloads | Last updated |
---|---|---|
2.0.0 | 129,615 | 7/8/2022 |
2.0.0-SNAPSHOT-2 | 152 | 7/8/2022 |
2.0.0-SNAPSHOT | 158 | 6/29/2022 |
1.0.3 | 77,366 | 9/11/2020 |
1.0.2 | 1,028 | 11/15/2019 |