/Timers/Timer.cs |
@@ -12,21 +12,23 @@ |
{ |
public class Timer : IDisposable |
{ |
private readonly Action callback; |
private readonly Task CompletedTask = Task.FromResult(false); |
private Task Delay; |
private bool Disposed; |
private TimeSpan dueTime; |
private TimeSpan period; |
|
private CancellationTokenSource tokenSource; |
|
public Timer(Action callback, TimeSpan dueTime, TimeSpan period) |
public Timer() |
{ |
this.callback = callback; |
this.dueTime = dueTime; |
this.period = period; |
} |
|
Run(); |
public Timer(Action callback, TimeSpan dueTime, TimeSpan period) : this() |
{ |
Callback = callback; |
DueTime = dueTime; |
Period = period; |
|
Start(); |
} |
|
public Timer(Action callback, int dueTime, int period) |
@@ -48,8 +50,18 @@ |
{ |
} |
|
public Action Callback { set; get; } |
|
public TimeSpan DueTime { get; set; } = TimeSpan.Zero; |
|
public TimeSpan Period { get; set; } = TimeSpan.Zero; |
|
public void Dispose() |
{ |
// Stop the timer. |
Stop(); |
|
// Dispose the token. |
if (tokenSource != null) |
{ |
tokenSource.Cancel(); |
@@ -56,12 +68,18 @@ |
tokenSource.Dispose(); |
tokenSource = null; |
} |
|
// Set the disposed flag. |
Disposed = true; |
} |
|
private void Run() |
private void Start() |
{ |
// Cancel any previous timer. |
// Check if we have an installed callback and that there is at least a due time. |
if (Callback == null || DueTime.Equals(TimeSpan.Zero)) |
return; |
|
// Dispose the previous token source. |
if (tokenSource != null) |
{ |
tokenSource.Cancel(); |
@@ -73,21 +91,22 @@ |
tokenSource = new CancellationTokenSource(); |
|
Action tick = null; |
|
tick = () => |
{ |
Task.Run(() => callback(), tokenSource.Token); |
Task.Run(Callback, tokenSource.Token); |
if (Disposed) |
return; |
Delay = !period.Equals(0) ? Task.Delay(period, tokenSource.Token) : CompletedTask; |
if (Delay.IsCompleted) |
Delay = !Period.Equals(TimeSpan.Zero) ? Task.Delay(Period, tokenSource.Token) : CompletedTask; |
if (Disposed || Delay.IsCompleted) |
return; |
Delay.ContinueWith(t => tick(), tokenSource.Token); |
Delay.ContinueWith(o => tick(), tokenSource.Token); |
}; |
|
Delay = !dueTime.Equals(0) ? Task.Delay(dueTime, tokenSource.Token) : CompletedTask; |
if (Delay.IsCompleted) |
Delay = !DueTime.Equals(TimeSpan.Zero) ? Task.Delay(DueTime, tokenSource.Token) : CompletedTask; |
if (Disposed || Delay.IsCompleted) |
return; |
Delay.ContinueWith(t => tick(), tokenSource.Token); |
Delay.ContinueWith(o => tick(), tokenSource.Token); |
} |
|
public void Change(int dueTime, int period) |
@@ -102,10 +121,10 @@ |
|
public void Change(TimeSpan dueTime, TimeSpan period) |
{ |
this.dueTime = dueTime; |
this.period = period; |
DueTime = dueTime; |
Period = period; |
|
Run(); |
Start(); |
} |
|
public void Stop() |