##// END OF EJS Templates
working on runnable components
cin -
r257:440801d88019 v3
parent child
Show More
@@ -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 ScheduleTask(StartInternalAsync, ct, cookie);
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 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 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
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