wasSharp – Blame information for rev 21
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
10 | office | 1 | /////////////////////////////////////////////////////////////////////////// |
2 | // Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 // |
||
3 | // Please see: http://www.gnu.org/licenses/gpl.html for legal details, // |
||
4 | // rights of fair usage, the disclaimer and warranty conditions. // |
||
5 | /////////////////////////////////////////////////////////////////////////// |
||
6 | |||
7 | using System; |
||
8 | using System.Threading; |
||
9 | using System.Threading.Tasks; |
||
10 | |||
11 | namespace wasSharp.Timers |
||
12 | { |
||
13 | public class Timer : IDisposable |
||
14 | { |
||
20 | office | 15 | private readonly Task CompletedTask = Task.FromResult(false); |
10 | office | 16 | private Task Delay; |
17 | private bool Disposed; |
||
21 | office | 18 | |
20 | office | 19 | private CancellationTokenSource tokenSource; |
10 | office | 20 | |
21 | office | 21 | public Timer() |
10 | office | 22 | { |
21 | office | 23 | } |
20 | office | 24 | |
21 | office | 25 | public Timer(Action callback, TimeSpan dueTime, TimeSpan period) : this() |
26 | { |
||
27 | Callback = callback; |
||
28 | DueTime = dueTime; |
||
29 | Period = period; |
||
30 | |||
31 | Start(); |
||
10 | office | 32 | } |
33 | |||
20 | office | 34 | public Timer(Action callback, int dueTime, int period) |
35 | : this(callback, TimeSpan.FromMilliseconds(dueTime), TimeSpan.FromMilliseconds(period)) |
||
10 | office | 36 | { |
37 | } |
||
38 | |||
20 | office | 39 | public Timer(Action callback) : this(callback, TimeSpan.Zero, TimeSpan.Zero) |
10 | office | 40 | { |
41 | } |
||
42 | |||
20 | office | 43 | public Timer(Action callback, double dueTime, int period) |
44 | : this(callback, TimeSpan.FromMilliseconds(dueTime), TimeSpan.FromMilliseconds(period)) |
||
10 | office | 45 | { |
46 | } |
||
47 | |||
20 | office | 48 | public Timer(Action callback, uint dueTime, uint period) |
49 | : this(callback, TimeSpan.FromMilliseconds(dueTime), TimeSpan.FromMilliseconds(period)) |
||
10 | office | 50 | { |
51 | } |
||
52 | |||
21 | office | 53 | public Action Callback { set; get; } |
54 | |||
55 | public TimeSpan DueTime { get; set; } = TimeSpan.Zero; |
||
56 | |||
57 | public TimeSpan Period { get; set; } = TimeSpan.Zero; |
||
58 | |||
20 | office | 59 | public void Dispose() |
10 | office | 60 | { |
21 | office | 61 | // Stop the timer. |
62 | Stop(); |
||
63 | |||
64 | // Dispose the token. |
||
20 | office | 65 | if (tokenSource != null) |
66 | { |
||
67 | tokenSource.Cancel(); |
||
68 | tokenSource.Dispose(); |
||
69 | tokenSource = null; |
||
70 | } |
||
21 | office | 71 | |
72 | // Set the disposed flag. |
||
10 | office | 73 | Disposed = true; |
74 | } |
||
75 | |||
21 | office | 76 | private void Start() |
10 | office | 77 | { |
21 | office | 78 | // Check if we have an installed callback and that there is at least a due time. |
79 | if (Callback == null || DueTime.Equals(TimeSpan.Zero)) |
||
80 | return; |
||
81 | |||
82 | // Dispose the previous token source. |
||
20 | office | 83 | if (tokenSource != null) |
84 | { |
||
85 | tokenSource.Cancel(); |
||
86 | tokenSource.Dispose(); |
||
87 | tokenSource = null; |
||
88 | } |
||
10 | office | 89 | |
20 | office | 90 | // Create a new cancellation source. |
91 | tokenSource = new CancellationTokenSource(); |
||
10 | office | 92 | |
93 | Action tick = null; |
||
21 | office | 94 | |
10 | office | 95 | tick = () => |
96 | { |
||
21 | office | 97 | Task.Run(Callback, tokenSource.Token); |
10 | office | 98 | if (Disposed) |
99 | return; |
||
21 | office | 100 | Delay = !Period.Equals(TimeSpan.Zero) ? Task.Delay(Period, tokenSource.Token) : CompletedTask; |
101 | if (Disposed || Delay.IsCompleted) |
||
10 | office | 102 | return; |
21 | office | 103 | Delay.ContinueWith(o => tick(), tokenSource.Token); |
10 | office | 104 | }; |
20 | office | 105 | |
21 | office | 106 | Delay = !DueTime.Equals(TimeSpan.Zero) ? Task.Delay(DueTime, tokenSource.Token) : CompletedTask; |
107 | if (Disposed || Delay.IsCompleted) |
||
10 | office | 108 | return; |
21 | office | 109 | Delay.ContinueWith(o => tick(), tokenSource.Token); |
10 | office | 110 | } |
111 | |||
20 | office | 112 | public void Change(int dueTime, int period) |
10 | office | 113 | { |
20 | office | 114 | Change(TimeSpan.FromMilliseconds(dueTime), TimeSpan.FromMilliseconds(period)); |
10 | office | 115 | } |
116 | |||
20 | office | 117 | public void Change(uint dueTime, int period) |
10 | office | 118 | { |
20 | office | 119 | Change(TimeSpan.FromMilliseconds(dueTime), TimeSpan.FromMilliseconds(period)); |
10 | office | 120 | } |
20 | office | 121 | |
122 | public void Change(TimeSpan dueTime, TimeSpan period) |
||
123 | { |
||
21 | office | 124 | DueTime = dueTime; |
125 | Period = period; |
||
20 | office | 126 | |
21 | office | 127 | Start(); |
20 | office | 128 | } |
129 | |||
130 | public void Stop() |
||
131 | { |
||
132 | Change(0, 0); |
||
133 | } |
||
10 | office | 134 | } |
135 | } |