Skip to content

Instantly share code, notes, and snippets.

@Kilowhisky
Last active August 16, 2023 15:54
Show Gist options
  • Save Kilowhisky/2b28e7d74189c643c4bc1c5ba3a15e42 to your computer and use it in GitHub Desktop.
Save Kilowhisky/2b28e7d74189c643c4bc1c5ba3a15e42 to your computer and use it in GitHub Desktop.
C# Class that debounces an action denoted by a given key
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using System.Threading;
namespace Utils
{
public interface IDebounceAction
{
void Debounce(string key, Func<Task> debouncedFunc, TimeSpan debouncedTime, CancellationTokenSource cancellationToken = null);
IReadOnlyDictionary<string, DelayedAction> GetPending();
}
public class DelayedAction
{
public CancellationTokenSource Token { get; init; }
public Task Task { get; init; }
}
public class DebounceAction : IDebounceAction
{
private readonly ConcurrentDictionary<string, DelayedAction> _debouncedActions = new();
public void Debounce(string key, Func<Task> debouncedFunc, TimeSpan debouncedTime, CancellationTokenSource cancellationToken = null)
{
var cancel = cancellationToken ?? new CancellationTokenSource();
var task = Task.Run(async () =>
{
await Task.Delay(debouncedTime, cancel.Token);
_debouncedActions.TryRemove(key, out _);
await debouncedFunc();
}, cancel.Token);
var action = new DelayedAction
{
Token = cancel,
Task = task,
};
_debouncedActions.AddOrUpdate(key, action, (key, existingAction) =>
{
existingAction.Token.Cancel();
existingAction.Token.Dispose();
return action;
});
}
public IReadOnlyDictionary<string, DelayedAction> GetPending()
{
return new ReadOnlyDictionary<string, DelayedAction>(_debouncedActions);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment