Soenneker.Utils.Debounce
11.0.99
Prefix Reserved
dotnet add package Soenneker.Utils.Debounce --version 11.0.99
NuGet\Install-Package Soenneker.Utils.Debounce -Version 11.0.99
<PackageReference Include="Soenneker.Utils.Debounce" Version="11.0.99" />
<PackageVersion Include="Soenneker.Utils.Debounce" Version="11.0.99" />
<PackageReference Include="Soenneker.Utils.Debounce" />
paket add Soenneker.Utils.Debounce --version 11.0.99
#r "nuget: Soenneker.Utils.Debounce, 11.0.99"
#:package Soenneker.Utils.Debounce@11.0.99
#addin nuget:?package=Soenneker.Utils.Debounce&version=11.0.99
#tool nuget:?package=Soenneker.Utils.Debounce&version=11.0.99
Soenneker.Utils.Debounce
A thread-safe trailing-edge debouncer for synchronous or Task-based callbacks.
Installation
dotnet add package Soenneker.Utils.Debounce
Usage
Keep one debouncer for each independent stream of calls. Every call replaces that debouncer's pending callback and restarts its timer:
await using var searchDebouncer = new Debouncer();
void OnTextChanged(string text, CancellationToken cancellationToken)
{
searchDebouncer.Debounce(
delayMs: 300,
action: async ct =>
{
SearchResults results = await SearchAsync(text, ct);
UpdateUi(results);
},
cancellationToken: cancellationToken);
}
If calls continue arriving inside the 300 ms window, only the callback from the last call remains pending. Different logical operations should use different Debouncer instances; calls made through one instance intentionally replace each other.
The cancellation token is the caller-supplied token. It prevents a pending callback from starting when already cancelled and is passed to the callback, but the debouncer does not cancel it when a newer call arrives. Work that has already started is not stopped or awaited by a later Debounce() call.
Leading and trailing execution
debouncer.Debounce(
delayMs: 500,
action: ct => RecordBurstAsync(ct),
runLeading: true);
runLeading: true runs the first callback in a burst immediately and still schedules a trailing callback after the quiet period. The leading callback can overlap the trailing callback if it runs longer than the delay; callback code must be safe for that possibility.
Lifetime and errors
Dispose the debouncer from its owner, not from inside one of its callbacks. Disposal drops pending work, prevents new calls, and waits for callbacks that already started. It does not cancel those running callbacks.
Debounce() is fire-and-forget and cannot return callback failures to its caller. Catch and log exceptions inside asynchronous callbacks when failure visibility matters:
debouncer.Debounce(250, async ct =>
{
try
{
await SaveAsync(ct);
}
catch (Exception exception)
{
logger.LogError(exception, "Debounced save failed");
}
});
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net11.0 is compatible. |
-
net11.0
- Soenneker.Extensions.Task (>= 11.0.143)
- Soenneker.Extensions.ValueTask (>= 11.0.136)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Soenneker.Utils.Debounce:
| Package | Downloads |
|---|---|
|
Soenneker.Quark.Suite
Shadcn-powered Blazor UI, refined and modular. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 11.0.99 | 1,892 | 11/11/2026 |
| 11.0.98 | 215 | 11/11/2026 |
| 11.0.97 | 47 | 11/11/2026 |
| 11.0.96 | 7,900 | 10/26/2026 |
| 11.0.95 | 97 | 10/26/2026 |
| 4.0.94 | 4,802 | 10/15/2026 |
| 4.0.93 | 111 | 10/15/2026 |
| 4.0.92 | 105 | 10/14/2026 |
| 4.0.91 | 604 | 10/14/2026 |
| 4.0.90 | 116 | 10/14/2026 |
| 4.0.84 | 465 | 10/13/2026 |
| 4.0.83 | 104 | 10/13/2026 |
| 4.0.80 | 699 | 10/12/2026 |
| 4.0.79 | 98 | 10/11/2026 |
| 4.0.78 | 105 | 10/11/2026 |
| 4.0.77 | 10,147 | 9/24/2026 |
| 4.0.76 | 107 | 9/24/2026 |
| 4.0.75 | 3,563 | 9/15/2026 |
| 4.0.74 | 120 | 9/15/2026 |
| 4.0.73 | 3,066 | 9/12/2026 |
Updated Multiple NuGet packages