Mercurial > pub > ImplabNet
comparison Implab/Components/RunnableComponent.cs @ 256:c52691faaf21 v3
Removed obsolete App, ComponentContainer
Extracted IAsyncComponent interface
Working on RunnableComponent
| author | cin |
|---|---|
| date | Wed, 11 Apr 2018 03:05:14 +0300 |
| parents | 6f4630d0bcd9 |
| children | 440801d88019 |
comparison
equal
deleted
inserted
replaced
| 255:b00441e04738 | 256:c52691faaf21 |
|---|---|
| 10 /// </summary> | 10 /// </summary> |
| 11 /// <remarks> | 11 /// <remarks> |
| 12 /// This class provides a basic lifecycle from the creation to the | 12 /// This class provides a basic lifecycle from the creation to the |
| 13 /// termination of the component. | 13 /// termination of the component. |
| 14 /// </remarks> | 14 /// </remarks> |
| 15 public class RunnableComponent : IRunnable, IInitializable, IDisposable { | 15 public class RunnableComponent : IAsyncComponent, IRunnable, IInitializable, IDisposable { |
| 16 | 16 |
| 17 /// <summary> | 17 /// <summary> |
| 18 /// This class bounds <see cref="CancellationTokenSource"/> lifetime to the task, | 18 /// This class bounds <see cref="CancellationTokenSource"/> lifetime to the task, |
| 19 /// when the task completes the associated token source will be disposed. | 19 /// when the task completes the associated token source will be disposed. |
| 20 /// </summary> | 20 /// </summary> |
| 78 } | 78 } |
| 79 | 79 |
| 80 } | 80 } |
| 81 | 81 |
| 82 // this lock is used to synchronize state flow of the component during | 82 // this lock is used to synchronize state flow of the component during |
| 83 // completions or the operations. | 83 // processing calls from a client and internal processes. |
| 84 readonly object m_lock = new object(); | 84 readonly object m_lock = new object(); |
| 85 | 85 |
| 86 // current operation cookie, used to check wheather a call to | 86 // current operation cookie, used to check wheather a call to |
| 87 // MoveSuccess/MoveFailed method belongs to the current | 87 // MoveSuccess/MoveFailed method belongs to the current |
| 88 // operation, if cookies didn't match ignore completion result. | 88 // operation, if cookies didn't match ignore completion result. |
| 89 object m_cookie; | 89 object m_cookie; |
| 90 | 90 |
| 91 // AsyncOperationDscriptor aggregates a task and it's cancellation token | |
| 91 AsyncOperationDescriptor m_current = AsyncOperationDescriptor.None; | 92 AsyncOperationDescriptor m_current = AsyncOperationDescriptor.None; |
| 92 | 93 |
| 93 ExecutionState m_state; | 94 ExecutionState m_state; |
| 94 | 95 |
| 95 | 96 |
| 150 | 151 |
| 151 public void Initialize() { | 152 public void Initialize() { |
| 152 var cookie = new object(); | 153 var cookie = new object(); |
| 153 if (MoveInitialize(cookie)) | 154 if (MoveInitialize(cookie)) |
| 154 ScheduleTask(InitializeInternalAsync, CancellationToken.None, cookie); | 155 ScheduleTask(InitializeInternalAsync, CancellationToken.None, cookie); |
| 156 else | |
| 157 throw new InvalidOperationException(); | |
| 155 } | 158 } |
| 156 | 159 |
| 157 /// <summary> | 160 /// <summary> |
| 158 /// This method is used for initialization during a component creation. | 161 /// This method is used for initialization during a component creation. |
| 159 /// </summary> | 162 /// </summary> |
| 169 | 172 |
| 170 public void Start(CancellationToken ct) { | 173 public void Start(CancellationToken ct) { |
| 171 var cookie = new object(); | 174 var cookie = new object(); |
| 172 if (MoveStart(cookie)) | 175 if (MoveStart(cookie)) |
| 173 ScheduleTask(StartInternalAsync, ct, cookie); | 176 ScheduleTask(StartInternalAsync, ct, cookie); |
| 177 else | |
| 178 throw new InvalidOperationException(); | |
| 174 } | 179 } |
| 175 | 180 |
| 176 protected virtual Task StartInternalAsync(CancellationToken ct) { | 181 protected virtual Task StartInternalAsync(CancellationToken ct) { |
| 177 return Task.CompletedTask; | 182 return Task.CompletedTask; |
| 178 } | 183 } |
| 179 | 184 |
| 180 public void Stop(CancellationToken ct) { | 185 public void Stop(CancellationToken ct) { |
| 181 var cookie = new object(); | 186 var cookie = new object(); |
| 182 if (MoveStop(cookie)) | 187 if (MoveStop(cookie)) |
| 183 ScheduleTask(StopAsync, ct, cookie); | 188 ScheduleTask(StopAsync, ct, cookie); |
| 189 else | |
| 190 throw new InvalidOperationException(); | |
| 184 } | 191 } |
| 185 | 192 |
| 186 async Task StopAsync(CancellationToken ct) { | 193 async Task StopAsync(CancellationToken ct) { |
| 187 m_current.Cancel(); | 194 m_current.Cancel(); |
| 188 await Completion; | 195 await Completion; |
| 192 await StopInternalAsync(ct); | 199 await StopInternalAsync(ct); |
| 193 } | 200 } |
| 194 | 201 |
| 195 protected virtual Task StopInternalAsync(CancellationToken ct) { | 202 protected virtual Task StopInternalAsync(CancellationToken ct) { |
| 196 return Task.CompletedTask; | 203 return Task.CompletedTask; |
| 204 } | |
| 205 | |
| 206 protected void Fail(Exception err) { | |
| 207 lock(m_lock) { | |
| 208 if (m_state != ExecutionState.Running) | |
| 209 return; | |
| 210 m_cookie = new object(); | |
| 211 LastError = err; | |
| 212 State = ExecutionState.Failed; | |
| 213 } | |
| 197 } | 214 } |
| 198 | 215 |
| 199 | 216 |
| 200 #region state management | 217 #region state management |
| 201 | 218 |
| 254 LastError = err; | 271 LastError = err; |
| 255 State = ExecutionState.Failed; | 272 State = ExecutionState.Failed; |
| 256 } | 273 } |
| 257 } | 274 } |
| 258 | 275 |
| 259 | 276 void ScheduleTask(Func<CancellationToken, Task> next, CancellationToken ct, object cookie) { |
| 260 | 277 |
| 261 protected async void ScheduleTask(Func<CancellationToken, Task> next, CancellationToken ct, object cookie) { | 278 m_current = AsyncOperationDescriptor.Create(async (x) => { |
| 262 try { | 279 try { |
| 263 m_current = AsyncOperationDescriptor.Create(next, ct); | 280 await next(x); |
| 264 await m_current.Task; | 281 MoveSuccess(cookie); |
| 265 MoveSuccess(cookie); | 282 } catch (Exception e) { |
| 266 } catch (Exception e) { | 283 MoveFailed(e, cookie); |
| 267 MoveFailed(e, cookie); | 284 } |
| 268 } | 285 }, ct); |
| 269 } | 286 } |
| 270 | 287 |
| 271 #endregion | 288 #endregion |
| 272 } | 289 } |
| 273 } | 290 } |
