public class Throttle<T>
{
private readonly Func<Task<T>> _initialFn;
private readonly TimeSpan _throttleTime;
private TaskCompletionSource<T> _tcs;
private DateTime _lastExecutionTime;
private readonly object _lock = new object();
public Throttle(TimeSpan throttleTime, Func<Task<T>> initialFn)
{
_initialFn = initialFn ?? throw new ArgumentNullException(nameof(initialFn));
_throttleTime = throttleTime;
_tcs = new TaskCompletionSource<T>();
_lastExecutionTime = DateTime.MinValue;
}
private bool IsThrottleTimeElapsed()
{
return DateTime.UtcNow - _lastExecutionTime >= _throttleTime;
}
public void ClearLastExecutionTime()
{
lock (_lock)
{
_lastExecutionTime = DateTime.MinValue;
}
}
private async Task<T> ExecuteInitialFunctionAsync()
{
try
{
var result = await _initialFn();
_tcs.TrySetResult(result);
}
catch (Exception ex)
{
_tcs.TrySetException(ex);
}
return await _tcs.Task;
}
public Task<T> ExecuteAsync()
{
Task<T> taskToAwait;
lock (_lock)
{
if (!IsThrottleTimeElapsed())
{
taskToAwait = _tcs.Task;
}
else
{
_tcs = new TaskCompletionSource<T>();
_lastExecutionTime = DateTime.UtcNow;
taskToAwait = ExecuteInitialFunctionAsync();
}
}
return taskToAwait;
}
}829200cookie-checkC# Throttle Function