Mercurial > pub > ImplabNet
comparison Implab/Components/RunnableComponent.cs @ 262:f1696cdc3d7a v3 v3.0.8
Added IInitializable.Initialize() overload
Added IRunnable.Start(), IRunnable.Start() overloads
Fixed cancellation of the current operation when Stop() is called
More tests
author | cin |
---|---|
date | Mon, 16 Apr 2018 02:12:39 +0300 |
parents | 547a2fc0d93e |
children |
comparison
equal
deleted
inserted
replaced
261:05a87f575512 | 262:f1696cdc3d7a |
---|---|
169 /// during a normal disposing or during GC.</param> | 169 /// during a normal disposing or during GC.</param> |
170 protected virtual void Dispose(bool disposing) { | 170 protected virtual void Dispose(bool disposing) { |
171 } | 171 } |
172 | 172 |
173 public void Initialize() { | 173 public void Initialize() { |
174 Initialize(CancellationToken.None); | |
175 } | |
176 | |
177 public void Initialize(CancellationToken ct) { | |
174 var cookie = new object(); | 178 var cookie = new object(); |
175 if (MoveInitialize(cookie)) | 179 if (MoveInitialize(cookie)) |
176 Safe.NoWait(ScheduleTask(InitializeInternalAsync, CancellationToken.None, cookie)); | 180 Safe.NoWait(ScheduleTask(InitializeInternalAsync, ct, cookie)); |
177 else | 181 else |
178 throw new InvalidOperationException(); | 182 throw new InvalidOperationException(); |
179 } | 183 } |
180 | 184 |
181 /// <summary> | 185 /// <summary> |
189 /// </remarks> | 193 /// </remarks> |
190 protected virtual Task InitializeInternalAsync(CancellationToken ct) { | 194 protected virtual Task InitializeInternalAsync(CancellationToken ct) { |
191 return Task.CompletedTask; | 195 return Task.CompletedTask; |
192 } | 196 } |
193 | 197 |
198 public void Start() { | |
199 Start(CancellationToken.None); | |
200 } | |
201 | |
194 public void Start(CancellationToken ct) { | 202 public void Start(CancellationToken ct) { |
195 var cookie = new object(); | 203 var cookie = new object(); |
196 if (MoveStart(cookie)) | 204 if (MoveStart(cookie)) |
197 Safe.NoWait(ScheduleStartAndRun(ct, cookie)); | 205 Safe.NoWait(ScheduleStartAndRun(ct, cookie)); |
198 else | 206 else |
218 /// </summary> | 226 /// </summary> |
219 protected virtual void RunInternal() { | 227 protected virtual void RunInternal() { |
220 | 228 |
221 } | 229 } |
222 | 230 |
231 public void Stop() { | |
232 Stop(CancellationToken.None); | |
233 } | |
234 | |
223 public void Stop(CancellationToken ct) { | 235 public void Stop(CancellationToken ct) { |
224 var cookie = new object(); | 236 var cookie = new object(); |
225 if (MoveStop(cookie)) | 237 if (MoveStop(cookie)) |
226 Safe.NoWait(ScheduleTask(StopAsync, ct, cookie)); | 238 Safe.NoWait(ScheduleTask(StopAsync, ct, cookie)); |
227 else | 239 else |
228 throw new InvalidOperationException(); | 240 throw new InvalidOperationException(); |
229 } | 241 } |
230 | 242 |
231 async Task StopAsync(CancellationToken ct) { | 243 async Task StopAsync(CancellationToken ct) { |
232 m_current.Cancel(); | 244 m_current.Cancel(); |
233 await Completion; | 245 |
246 try { | |
247 await Completion; | |
248 } catch(OperationCanceledException) { | |
249 // OK | |
250 } | |
234 | 251 |
235 ct.ThrowIfCancellationRequested(); | 252 ct.ThrowIfCancellationRequested(); |
236 | 253 |
237 await StopInternalAsync(ct); | 254 await StopInternalAsync(ct); |
238 } | 255 } |
300 break; | 317 break; |
301 } | 318 } |
302 } | 319 } |
303 } | 320 } |
304 | 321 |
305 void MoveFailed(Exception err, object cookie) { | 322 bool MoveFailed(Exception err, object cookie) { |
306 lock (m_lock) { | 323 lock (m_lock) { |
307 if (m_cookie != cookie) | 324 if (m_cookie != cookie) |
308 return; | 325 return false; |
309 LastError = err; | 326 LastError = err; |
310 State = ExecutionState.Failed; | 327 State = ExecutionState.Failed; |
328 return true; | |
311 } | 329 } |
312 } | 330 } |
313 | 331 |
314 Task ScheduleTask(Func<CancellationToken, Task> next, CancellationToken ct, object cookie) { | 332 Task ScheduleTask(Func<CancellationToken, Task> next, CancellationToken ct, object cookie) { |
315 | 333 |