using System.Threading.Tasks;
public static void Main()
var timer = new CountDownTimer();
var progress = new CountDownPercentage(e =>
var remainingTime = e.RemainingTime;
var percentage = e.ProgressPercentage;
Console.WriteLine("{0}, {1}%", remainingTime, percentage);
timer.Wait(4, progress).Wait();
Console.WriteLine("Hello World. Times up");
public class CountDownPercentage : IProgress<CountdownReport>
private Action<CountdownReport> handler;
public CountDownPercentage(Action<CountdownReport> handler)
public void Report(CountdownReport value)
public class CountDownTimer
TimeSpan delay = TimeSpan.FromSeconds(1);
public Task Wait(int seconds, IProgress<CountdownReport> progress = null)
return Wait(seconds, CancellationToken.None, progress);
public async Task Wait(int seconds, CancellationToken cancellationToken = default (CancellationToken), IProgress<CountdownReport> progress = null)
var total = TimeSpan.FromSeconds(seconds);
var current = total.TotalSeconds;
reportProgress(progress, total, current);
await Task.Delay(delay, cancellationToken);
catch (TaskCanceledException e)
reportProgress(progress, total, current);
private void reportProgress(IProgress<CountdownReport> progress, TimeSpan total, double current)
var percentageRemaining = (int)((current / total.TotalSeconds) * 100);
var progressPercentage = 100 - percentageRemaining;
var timeRemaining = TimeSpan.FromSeconds(current);
var report = new CountdownReport{InitialTime = total, RemainingTime = timeRemaining, ProgressPercentage = progressPercentage, RemainingPercentage = percentageRemaining};
public class CountdownReport
public TimeSpan InitialTime
public int ProgressPercentage
public int RemainingPercentage
public TimeSpan RemainingTime