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