Auto status change to "Under Review"
@@ -12,7 +12,7 namespace Implab.Components { | |||||
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 : IAsyncComponent, IRunnable, IInitializable, IDisposable { |
|
15 | public abstract 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, | |
@@ -93,6 +93,15 namespace Implab.Components { | |||||
93 |
|
93 | |||
94 | ExecutionState m_state; |
|
94 | ExecutionState m_state; | |
95 |
|
95 | |||
|
96 | /// <summary> | |||
|
97 | /// ΠΠ±ΡΠ΅ΠΊΡ ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π΄Π»Ρ ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠ΅Π½ΠΈΡ ΡΠΎΠ²ΠΌΠ΅ΡΡΠ½ΠΎΠ³ΠΎ Π΄ΠΎΡΡΡΠΏΠ° | |||
|
98 | /// ΠΊΠ»ΠΈΠ΅Π½ΡΠ° ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΡ ΠΈ ΠΏΡΠΎΡΠ΅ΡΡΠΎΠ², ΠΏΡΠΎΡΠ΅ΠΊΠ°ΡΡΠΈΡ Π²Π½ΡΡΡΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΡ, ΠΊ ΠΎΠ±ΡΠ΅ΠΌΡ | |||
|
99 | /// ΡΠΎΡΡΠΎΡΠ½ΠΈΡ, Ρ.Π΅.true ΡΠ°ΠΊΠΈΠΌ ΡΠ²ΠΎΠΉΡΡΠ²Π°ΠΌ, ΠΊΠ°ΠΊ <see cref="State"/>, | |||
|
100 | /// <see cref="LastError"/>. ΠΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΈ ΡΠΎΠ±ΡΡΠΈΡ <see cref="StateChanged"/> | |||
|
101 | /// Π²ΡΠ·ΡΠ²Π°ΡΡΡΡ ΡΠΆΠ΅ Ρ ΡΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½Π½ΠΎΠΉ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠΎΠΉ, ΠΏΠΎΡΡΠΎΠΌΡ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½Π°Ρ | |||
|
102 | /// ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΡ Π½Π΅ ΡΡΠ΅Π±ΡΠ΅ΡΡΡ. | |||
|
103 | /// </summary> | |||
|
104 | public object SynchronizationObject { get { return m_lock; } } | |||
96 |
|
105 | |||
97 | protected RunnableComponent(bool initialized) { |
|
106 | protected RunnableComponent(bool initialized) { | |
98 | State = initialized ? ExecutionState.Ready : ExecutionState.Created; |
|
107 | State = initialized ? ExecutionState.Ready : ExecutionState.Created; | |
@@ -117,6 +126,11 namespace Implab.Components { | |||||
117 |
|
126 | |||
118 | public Exception LastError { get; private set; } |
|
127 | public Exception LastError { get; private set; } | |
119 |
|
128 | |||
|
129 | /// <summary> | |||
|
130 | /// Π‘ΠΎΠ±ΡΡΠΈΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ ΡΠΎΡΡΠΎΡΠ½ΠΈΡ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΡ.see ΠΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΈ Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΡΠΎΠ±ΡΡΠΈΡ | |||
|
131 | /// Π²ΡΠ·ΡΠ²Π°ΡΡΡΡ Π²Π½ΡΡΡΠΈ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠΈ <see cref="SynchronizationObject"/> ΠΈ Π΄ΠΎΠ»ΠΆΠ½Ρ | |||
|
132 | /// Π²ΡΠΏΠΎΠ»Π½ΡΡΡΡΡ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡΠ½ΠΎ Π±ΡΡΡΡΠΎ. | |||
|
133 | /// </summary> | |||
120 | public event EventHandler<StateChangeEventArgs> StateChanged; |
|
134 | public event EventHandler<StateChangeEventArgs> StateChanged; | |
121 |
|
135 | |||
122 | /// <summary> |
|
136 | /// <summary> | |
@@ -130,6 +144,13 namespace Implab.Components { | |||||
130 | /// </remarks> |
|
144 | /// </remarks> | |
131 | public void Dispose() { |
|
145 | public void Dispose() { | |
132 | bool dispose = false; |
|
146 | bool dispose = false; | |
|
147 | lock (SynchronizationObject) { | |||
|
148 | if (m_state != ExecutionState.Disposed) { | |||
|
149 | dispose = true; | |||
|
150 | m_state = ExecutionState.Disposed; | |||
|
151 | m_cookie = new object(); | |||
|
152 | } | |||
|
153 | } | |||
133 | if (dispose) { |
|
154 | if (dispose) { | |
134 | Dispose(true); |
|
155 | Dispose(true); | |
135 | GC.SuppressFinalize(this); |
|
156 | GC.SuppressFinalize(this); | |
@@ -152,7 +173,7 namespace Implab.Components { | |||||
152 | public void Initialize() { |
|
173 | public void Initialize() { | |
153 | var cookie = new object(); |
|
174 | var cookie = new object(); | |
154 | if (MoveInitialize(cookie)) |
|
175 | if (MoveInitialize(cookie)) | |
155 | ScheduleTask(InitializeInternalAsync, CancellationToken.None, cookie); |
|
176 | Safe.NoWait(ScheduleTask(InitializeInternalAsync, CancellationToken.None, cookie)); | |
156 | else |
|
177 | else | |
157 | throw new InvalidOperationException(); |
|
178 | throw new InvalidOperationException(); | |
158 | } |
|
179 | } | |
@@ -173,19 +194,36 namespace Implab.Components { | |||||
173 | public void Start(CancellationToken ct) { |
|
194 | public void Start(CancellationToken ct) { | |
174 | var cookie = new object(); |
|
195 | var cookie = new object(); | |
175 | if (MoveStart(cookie)) |
|
196 | if (MoveStart(cookie)) | |
176 |
S |
|
197 | Safe.NoWait(ScheduleStartAndRun(ct, cookie)); | |
177 | else |
|
198 | else | |
178 | throw new InvalidOperationException(); |
|
199 | throw new InvalidOperationException(); | |
179 | } |
|
200 | } | |
180 |
|
201 | |||
|
202 | async Task ScheduleStartAndRun(CancellationToken ct, object cookie) { | |||
|
203 | try { | |||
|
204 | await ScheduleTask(StartInternalAsync, ct, cookie); | |||
|
205 | RunInternal(); | |||
|
206 | } catch (Exception err) { | |||
|
207 | Fail(err); | |||
|
208 | } | |||
|
209 | } | |||
|
210 | ||||
181 | protected virtual Task StartInternalAsync(CancellationToken ct) { |
|
211 | protected virtual Task StartInternalAsync(CancellationToken ct) { | |
182 | return Task.CompletedTask; |
|
212 | return Task.CompletedTask; | |
183 | } |
|
213 | } | |
184 |
|
214 | |||
|
215 | /// <summary> | |||
|
216 | /// This method is called after the component is enetered running state, | |||
|
217 | /// use this method to | |||
|
218 | /// </summary> | |||
|
219 | protected virtual void RunInternal() { | |||
|
220 | ||||
|
221 | } | |||
|
222 | ||||
185 | public void Stop(CancellationToken ct) { |
|
223 | public void Stop(CancellationToken ct) { | |
186 | var cookie = new object(); |
|
224 | var cookie = new object(); | |
187 | if (MoveStop(cookie)) |
|
225 | if (MoveStop(cookie)) | |
188 | ScheduleTask(StopAsync, ct, cookie); |
|
226 | Safe.NoWait(ScheduleTask(StopAsync, ct, cookie)); | |
189 | else |
|
227 | else | |
190 | throw new InvalidOperationException(); |
|
228 | throw new InvalidOperationException(); | |
191 | } |
|
229 | } | |
@@ -273,9 +311,9 namespace Implab.Components { | |||||
273 | } |
|
311 | } | |
274 | } |
|
312 | } | |
275 |
|
313 | |||
276 |
|
|
314 | Task ScheduleTask(Func<CancellationToken, Task> next, CancellationToken ct, object cookie) { | |
277 |
|
315 | |||
278 |
|
|
316 | var op = AsyncOperationDescriptor.Create(async (x) => { | |
279 | try { |
|
317 | try { | |
280 | await next(x); |
|
318 | await next(x); | |
281 | MoveSuccess(cookie); |
|
319 | MoveSuccess(cookie); | |
@@ -283,6 +321,9 namespace Implab.Components { | |||||
283 | MoveFailed(e, cookie); |
|
321 | MoveFailed(e, cookie); | |
284 | } |
|
322 | } | |
285 | }, ct); |
|
323 | }, ct); | |
|
324 | ||||
|
325 | m_current = op; | |||
|
326 | return op.Task; | |||
286 | } |
|
327 | } | |
287 |
|
328 | |||
288 | #endregion |
|
329 | #endregion |
General Comments 3
ok, latest stable version should be in default
You need to be logged in to leave comments.
Login now