/Timers/Timer.cs |
@@ -0,0 +1,114 @@ |
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 // |
// Please see: http://www.gnu.org/licenses/gpl.html for legal details, // |
// rights of fair usage, the disclaimer and warranty conditions. // |
/////////////////////////////////////////////////////////////////////////// |
|
using System; |
using System.Threading; |
using System.Threading.Tasks; |
|
namespace wasSharp.Timers |
{ |
public delegate void TimerCallback(object state); |
|
public class Timer : IDisposable |
{ |
private static readonly Task CompletedTask = Task.FromResult(false); |
private readonly TimerCallback Callback; |
private readonly object State; |
private Task Delay; |
private bool Disposed; |
private int Period; |
private CancellationTokenSource TokenSource; |
|
public Timer(TimerCallback callback, object state, int dueTime, int period) |
{ |
Callback = callback; |
State = state; |
Period = period; |
Reset(dueTime); |
} |
|
public Timer(TimerCallback callback, object state, TimeSpan dueTime, TimeSpan period) |
: this(callback, state, (int) dueTime.TotalMilliseconds, (int) period.TotalMilliseconds) |
{ |
} |
|
public Timer(TimerCallback callback) : this(callback, null, TimeSpan.Zero, TimeSpan.Zero) |
{ |
} |
|
public void Dispose() |
{ |
Dispose(true); |
GC.SuppressFinalize(this); |
} |
|
~Timer() |
{ |
Dispose(false); |
} |
|
private void Dispose(bool cleanUpManagedObjects) |
{ |
if (cleanUpManagedObjects) |
Cancel(); |
Disposed = true; |
} |
|
public void Change(int dueTime, int period) |
{ |
Period = period; |
Reset(dueTime); |
} |
|
public void Change(uint dueTime, int period) |
{ |
Period = period; |
Change((int) dueTime, period); |
} |
|
public void Change(TimeSpan dueTime, TimeSpan period) |
{ |
Change((int) dueTime.TotalMilliseconds, (int) period.TotalMilliseconds); |
} |
|
private void Reset(int due) |
{ |
Cancel(); |
if (due <= 0) |
return; |
TokenSource = new CancellationTokenSource(); |
Action tick = null; |
tick = () => |
{ |
Task.Run(() => Callback(State)); |
if (Disposed) |
return; |
Delay = Period > 0 ? Task.Delay(Period, TokenSource.Token) : CompletedTask; |
if (Delay.IsCompleted) |
return; |
Delay.ContinueWith(t => tick(), TokenSource.Token); |
}; |
Delay = due > 0 ? Task.Delay(due, TokenSource.Token) : CompletedTask; |
if (Delay.IsCompleted) |
return; |
Delay.ContinueWith(t => tick(), TokenSource.Token); |
} |
|
public void Stop() |
{ |
Change(0, 0); |
} |
|
private void Cancel() |
{ |
if (TokenSource == null) |
return; |
TokenSource.Cancel(); |
TokenSource.Dispose(); |
TokenSource = null; |
} |
} |
} |