##// END OF EJS Templates
working on runnable components
cin -
r257:440801d88019 v3
parent child
Show More
@@ -12,7 +12,7 namespace Implab.Components {
12 12 /// This class provides a basic lifecycle from the creation to the
13 13 /// termination of the component.
14 14 /// </remarks>
15 public class RunnableComponent : IAsyncComponent, IRunnable, IInitializable, IDisposable {
15 public abstract class RunnableComponent : IAsyncComponent, IRunnable, IInitializable, IDisposable {
16 16
17 17 /// <summary>
18 18 /// This class bounds <see cref="CancellationTokenSource"/> lifetime to the task,
@@ -93,6 +93,15 namespace Implab.Components {
93 93
94 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 106 protected RunnableComponent(bool initialized) {
98 107 State = initialized ? ExecutionState.Ready : ExecutionState.Created;
@@ -117,6 +126,11 namespace Implab.Components {
117 126
118 127 public Exception LastError { get; private set; }
119 128
129 /// <summary>
130 /// Π‘ΠΎΠ±Ρ‹Ρ‚ΠΈΠ΅ измСнСния состояния ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹.see ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ Π΄Π°Π½Π½ΠΎΠ³ΠΎ события
131 /// Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‚ΡΡ Π²Π½ΡƒΡ‚Ρ€ΠΈ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ <see cref="SynchronizationObject"/> ΠΈ Π΄ΠΎΠ»ΠΆΠ½Ρ‹
132 /// Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒΡΡ максимально быстро.
133 /// </summary>
120 134 public event EventHandler<StateChangeEventArgs> StateChanged;
121 135
122 136 /// <summary>
@@ -130,6 +144,13 namespace Implab.Components {
130 144 /// </remarks>
131 145 public void Dispose() {
132 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 154 if (dispose) {
134 155 Dispose(true);
135 156 GC.SuppressFinalize(this);
@@ -152,7 +173,7 namespace Implab.Components {
152 173 public void Initialize() {
153 174 var cookie = new object();
154 175 if (MoveInitialize(cookie))
155 ScheduleTask(InitializeInternalAsync, CancellationToken.None, cookie);
176 Safe.NoWait(ScheduleTask(InitializeInternalAsync, CancellationToken.None, cookie));
156 177 else
157 178 throw new InvalidOperationException();
158 179 }
@@ -173,19 +194,36 namespace Implab.Components {
173 194 public void Start(CancellationToken ct) {
174 195 var cookie = new object();
175 196 if (MoveStart(cookie))
176 ScheduleTask(StartInternalAsync, ct, cookie);
197 Safe.NoWait(ScheduleStartAndRun(ct, cookie));
177 198 else
178 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 211 protected virtual Task StartInternalAsync(CancellationToken ct) {
182 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 223 public void Stop(CancellationToken ct) {
186 224 var cookie = new object();
187 225 if (MoveStop(cookie))
188 ScheduleTask(StopAsync, ct, cookie);
226 Safe.NoWait(ScheduleTask(StopAsync, ct, cookie));
189 227 else
190 228 throw new InvalidOperationException();
191 229 }
@@ -273,9 +311,9 namespace Implab.Components {
273 311 }
274 312 }
275 313
276 void ScheduleTask(Func<CancellationToken, Task> next, CancellationToken ct, object cookie) {
314 Task ScheduleTask(Func<CancellationToken, Task> next, CancellationToken ct, object cookie) {
277 315
278 m_current = AsyncOperationDescriptor.Create(async (x) => {
316 var op = AsyncOperationDescriptor.Create(async (x) => {
279 317 try {
280 318 await next(x);
281 319 MoveSuccess(cookie);
@@ -283,6 +321,9 namespace Implab.Components {
283 321 MoveFailed(e, cookie);
284 322 }
285 323 }, ct);
324
325 m_current = op;
326 return op.Task;
286 327 }
287 328
288 329 #endregion
General Comments 3
Under Review
author

Auto status change to "Under Review"

Approved
author

ok, latest stable version should be in default

You need to be logged in to leave comments. Login now