wasSharp – Blame information for rev 41
?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 | |||
25 | office | 59 | public DateTime ScheduledTime |
60 | { |
||
61 | get; |
||
62 | set; |
||
63 | } |
||
64 | |||
20 | office | 65 | public void Dispose() |
10 | office | 66 | { |
21 | office | 67 | // Stop the timer. |
68 | Stop(); |
||
69 | |||
70 | // Dispose the token. |
||
20 | office | 71 | if (tokenSource != null) |
72 | { |
||
73 | tokenSource.Cancel(); |
||
74 | tokenSource.Dispose(); |
||
75 | tokenSource = null; |
||
76 | } |
||
21 | office | 77 | |
78 | // Set the disposed flag. |
||
10 | office | 79 | Disposed = true; |
80 | } |
||
81 | |||
21 | office | 82 | private void Start() |
10 | office | 83 | { |
41 | office | 84 | // Do not do anything if the object has been disposed. |
85 | if (Disposed) |
||
86 | return; |
||
87 | |||
21 | office | 88 | // Check if we have an installed callback and that there is at least a due time. |
89 | if (Callback == null || DueTime.Equals(TimeSpan.Zero)) |
||
90 | return; |
||
91 | |||
92 | // Dispose the previous token source. |
||
20 | office | 93 | if (tokenSource != null) |
94 | { |
||
95 | tokenSource.Cancel(); |
||
96 | tokenSource.Dispose(); |
||
97 | tokenSource = null; |
||
98 | } |
||
10 | office | 99 | |
20 | office | 100 | // Create a new cancellation source. |
101 | tokenSource = new CancellationTokenSource(); |
||
10 | office | 102 | |
103 | Action tick = null; |
||
21 | office | 104 | |
10 | office | 105 | tick = () => |
106 | { |
||
21 | office | 107 | Task.Run(Callback, tokenSource.Token); |
10 | office | 108 | if (Disposed) |
109 | return; |
||
25 | office | 110 | switch (!Period.Equals(TimeSpan.Zero)) |
111 | { |
||
112 | case true: |
||
113 | ScheduledTime = DateTime.UtcNow; |
||
114 | Delay = Task.Delay(DueTime, tokenSource.Token); |
||
115 | break; |
||
27 | office | 116 | |
25 | office | 117 | default: |
118 | Delay = CompletedTask; |
||
119 | break; |
||
120 | } |
||
21 | office | 121 | if (Disposed || Delay.IsCompleted) |
10 | office | 122 | return; |
21 | office | 123 | Delay.ContinueWith(o => tick(), tokenSource.Token); |
10 | office | 124 | }; |
20 | office | 125 | |
25 | office | 126 | switch (!DueTime.Equals(TimeSpan.Zero)) |
127 | { |
||
128 | case true: |
||
129 | ScheduledTime = DateTime.UtcNow; |
||
130 | Delay = Task.Delay(DueTime, tokenSource.Token); |
||
131 | break; |
||
27 | office | 132 | |
25 | office | 133 | default: |
134 | Delay = CompletedTask; |
||
135 | break; |
||
136 | } |
||
21 | office | 137 | if (Disposed || Delay.IsCompleted) |
10 | office | 138 | return; |
21 | office | 139 | Delay.ContinueWith(o => tick(), tokenSource.Token); |
10 | office | 140 | } |
141 | |||
20 | office | 142 | public void Change(int dueTime, int period) |
10 | office | 143 | { |
20 | office | 144 | Change(TimeSpan.FromMilliseconds(dueTime), TimeSpan.FromMilliseconds(period)); |
10 | office | 145 | } |
146 | |||
20 | office | 147 | public void Change(uint dueTime, int period) |
10 | office | 148 | { |
20 | office | 149 | Change(TimeSpan.FromMilliseconds(dueTime), TimeSpan.FromMilliseconds(period)); |
10 | office | 150 | } |
20 | office | 151 | |
152 | public void Change(TimeSpan dueTime, TimeSpan period) |
||
153 | { |
||
21 | office | 154 | DueTime = dueTime; |
155 | Period = period; |
||
20 | office | 156 | |
21 | office | 157 | Start(); |
20 | office | 158 | } |
159 | |||
160 | public void Stop() |
||
161 | { |
||
162 | Change(0, 0); |
||
163 | } |
||
10 | office | 164 | } |
27 | office | 165 | } |