using System;
using System.Threading.Tasks;
using Shouldly;
public class Program
{
public static async Task Main()
// Arrange.
var reportValue = 0;
var progress = new TimerProgress<int>((int value) => reportValue = value);
//progress.Report(1); // need to call the report at least once.
await Task.Delay(TimeSpan.FromSeconds(2)); // Need to wait more than 1 second for the report to work.
// Act.
progress.Report(5);
// Assert.
var s = progress._counter;
//s.ShouldBe(1); <-- COMMENT THIS OUT, THEN RE-RUN
reportValue.ShouldBe(5);
}
public class TimerProgress<T> : IProgress<T>
private readonly TimeSpan _intervalInMilliseconds;
private readonly IProgress<T> _progress;
private DateTime? _lastReportedOn;
public int _counter = 0;
public TimerProgress(Action<T> handler, double intervalInMillieconds = 1000)
if (intervalInMillieconds <= 0)
throw new ArgumentOutOfRangeException(nameof(intervalInMillieconds));
_intervalInMilliseconds = TimeSpan.FromMilliseconds(intervalInMillieconds);
_progress = new Progress<T>(handler);
_lastReportedOn = DateTime.UtcNow;
public void Report(T value)
var now = DateTime.UtcNow;
if (now - _lastReportedOn > _intervalInMilliseconds)
// We're due for a report!
_progress.Report(value);
_lastReportedOn = now;
_counter++;