Auto status change to "Under Review"
@@ -24,7 +24,7 namespace Implab.Test.Mock { | |||
|
24 | 24 | set; |
|
25 | 25 | } |
|
26 | 26 | |
|
27 |
public Action<bool |
|
|
27 | public Action<bool> MockDispose { | |
|
28 | 28 | get; |
|
29 | 29 | set; |
|
30 | 30 | } |
@@ -42,10 +42,10 namespace Implab.Test.Mock { | |||
|
42 | 42 | MockInit(); |
|
43 | 43 | } |
|
44 | 44 | |
|
45 |
protected override void Dispose(bool disposing |
|
|
45 | protected override void Dispose(bool disposing) { | |
|
46 | 46 | if (MockDispose != null) |
|
47 |
MockDispose(disposing |
|
|
48 |
base.Dispose(disposing |
|
|
47 | MockDispose(disposing); | |
|
48 | base.Dispose(disposing); | |
|
49 | 49 | } |
|
50 | 50 | } |
|
51 | 51 | } |
@@ -95,7 +95,7 namespace Implab.Test { | |||
|
95 | 95 | var comp = new MockRunnableComponent(true); |
|
96 | 96 | |
|
97 | 97 | bool disposed = false; |
|
98 |
comp.MockDispose = (disposing |
|
|
98 | comp.MockDispose = (disposing) => { | |
|
99 | 99 | disposed = true; |
|
100 | 100 | }; |
|
101 | 101 | |
@@ -115,7 +115,7 namespace Implab.Test { | |||
|
115 | 115 | var comp = new MockRunnableComponent(true, true); |
|
116 | 116 | |
|
117 | 117 | bool disposed = false; |
|
118 |
comp.MockDispose = (disposing |
|
|
118 | comp.MockDispose = (disposing) => { | |
|
119 | 119 | disposed = true; |
|
120 | 120 | }; |
|
121 | 121 | |
@@ -131,10 +131,8 namespace Implab.Test { | |||
|
131 | 131 | var comp = new MockRunnableComponent(true, true); |
|
132 | 132 | |
|
133 | 133 | bool disposed = false; |
|
134 | Exception lastError = null; | |
|
135 | comp.MockDispose = (disposing, error) => { | |
|
134 | comp.MockDispose = (disposing) => { | |
|
136 | 135 | disposed = true; |
|
137 | lastError = error; | |
|
138 | 136 | }; |
|
139 | 137 | |
|
140 | 138 | comp.Start().Join(1000); |
@@ -1,5 +1,6 | |||
|
1 | 1 | using Implab.Diagnostics; |
|
2 | 2 | using System; |
|
3 | using System.Diagnostics.CodeAnalysis; | |
|
3 | 4 | using System.Threading; |
|
4 | 5 | |
|
5 | 6 | namespace Implab.Components { |
@@ -81,6 +82,7 namespace Implab.Components { | |||
|
81 | 82 | } |
|
82 | 83 | } |
|
83 | 84 | |
|
85 | [SuppressMessage("Microsoft.Design", "CA1063:ImplementIDisposableCorrectly", Justification = "Dipose(bool) and GC.SuppessFinalize are called")] | |
|
84 | 86 | public void Dispose() { |
|
85 | 87 | if (Interlocked.Increment(ref m_disposed) == 1) { |
|
86 | 88 | Dispose(true); |
@@ -1,14 +1,22 | |||
|
1 | 1 | using System; |
|
2 | 2 | |
|
3 | 3 | namespace Implab.Components { |
|
4 | public interface IRunnable { | |
|
5 | 4 |
|
|
6 | /// Starts this instance. | |
|
5 | /// Interface for the component which performs a long running task. | |
|
6 | /// </summary> | |
|
7 | /// <remarks> | |
|
8 | /// <para>The component also should implement <see cref="IDisposable"/> interface to be able to release used resources.</para> | |
|
9 | /// <para>All methods of this interface must be a thread safe. If the operation is not applicable in the current state the | |
|
10 | /// method should throw an exception and keep the current state unchanged.</para> | |
|
11 | /// </remarks> | |
|
12 | public interface IRunnable : IDisposable { | |
|
13 | /// <summary> | |
|
14 | /// Starts this instance | |
|
7 | 15 | /// </summary> |
|
8 | 16 | IPromise Start(); |
|
9 | 17 | |
|
10 | 18 | /// <summary> |
|
11 | /// Stops this instance. After the instance is stopped it can't be started again, stopping should be treated as gracefull and async dispose. | |
|
19 | /// Stops this instance, after the instance is stopped it can move to Failed, Ready or Disposed state, in case with the last it can't be reused. | |
|
12 | 20 | /// </summary> |
|
13 | 21 | IPromise Stop(); |
|
14 | 22 |
@@ -144,11 +144,11 namespace Implab.Components { | |||
|
144 | 144 | return base.OnStop(); |
|
145 | 145 | } |
|
146 | 146 | |
|
147 |
protected override void Dispose(bool disposing |
|
|
147 | protected override void Dispose(bool disposing) { | |
|
148 | 148 | if (disposing) |
|
149 |
|
|
|
149 | m_timer.Dispose(); | |
|
150 | 150 | |
|
151 |
base.Dispose(disposing |
|
|
151 | base.Dispose(disposing); | |
|
152 | 152 | } |
|
153 | 153 | } |
|
154 | 154 | } |
@@ -1,4 +1,5 | |||
|
1 | 1 | using System; |
|
2 | using System.Diagnostics.CodeAnalysis; | |
|
2 | 3 | |
|
3 | 4 | namespace Implab.Components { |
|
4 | 5 | public abstract class RunnableComponent : IDisposable, IRunnable, IInitializable { |
@@ -333,30 +334,22 namespace Implab.Components { | |||
|
333 | 334 | /// especially if <see cref="Stop"/> method is failed. Using this method insted of <see cref="Stop()"/> may |
|
334 | 335 | /// lead to the data loss by the component. |
|
335 | 336 | /// </para></remarks> |
|
337 | [SuppressMessage("Microsoft.Design", "CA1063:ImplementIDisposableCorrectly", Justification = "Dipose(bool) and GC.SuppessFinalize are called")] | |
|
336 | 338 | public void Dispose() { |
|
337 | 339 | IPromise pending; |
|
338 | 340 | |
|
339 | 341 | lock (m_stateMachine) { |
|
340 | 342 | if (m_stateMachine.State == ExecutionState.Disposed) |
|
341 | 343 | return; |
|
342 |
|
|
|
344 | Move(Commands.Dispose, null, null); | |
|
343 | 345 | } |
|
344 | 346 | |
|
345 | 347 | GC.SuppressFinalize(this); |
|
346 | if (pending != null) { | |
|
347 | pending.Cancel(); | |
|
348 | pending.Timeout(DisposeTimeout).On( | |
|
349 | () => Dispose(true, null), | |
|
350 | err => Dispose(true, err), | |
|
351 | reason => Dispose(true, new OperationCanceledException("The operation is cancelled", reason)) | |
|
352 | ); | |
|
353 | } else { | |
|
354 | Dispose(true, null); | |
|
355 | } | |
|
348 | Dispose(true); | |
|
356 | 349 | } |
|
357 | 350 | |
|
358 | 351 | ~RunnableComponent() { |
|
359 |
Dispose(false |
|
|
352 | Dispose(false); | |
|
360 | 353 | } |
|
361 | 354 | |
|
362 | 355 | #endregion |
@@ -365,8 +358,8 namespace Implab.Components { | |||
|
365 | 358 | /// Releases all resources used by the component, called automatically, override this method to implement your cleanup. |
|
366 | 359 | /// </summary> |
|
367 | 360 | /// <param name="disposing">true if this method is called during normal dispose process.</param> |
|
368 |
/// <param name=" |
|
|
369 |
protected virtual void Dispose(bool disposing |
|
|
361 | /// <param name="pending">The operation which is currenty pending</param> | |
|
362 | protected virtual void Dispose(bool disposing) { | |
|
370 | 363 | |
|
371 | 364 | } |
|
372 | 365 |
@@ -274,7 +274,7 namespace Implab.Formats.JSON { | |||
|
274 | 274 | |
|
275 | 275 | protected override void Dispose(bool disposing) { |
|
276 | 276 | if (disposing) |
|
277 |
|
|
|
277 | m_scanner.Dispose(); | |
|
278 | 278 | } |
|
279 | 279 | |
|
280 | 280 | /// <summary> |
@@ -102,7 +102,7 namespace Implab.Formats.JSON { | |||
|
102 | 102 | |
|
103 | 103 | protected override void Dispose(bool disposing) { |
|
104 | 104 | if (disposing) |
|
105 |
|
|
|
105 | m_scanner.Dispose(); | |
|
106 | 106 | base.Dispose(disposing); |
|
107 | 107 | } |
|
108 | 108 | } |
@@ -120,8 +120,12 namespace Implab { | |||
|
120 | 120 | } |
|
121 | 121 | |
|
122 | 122 | public static IPromise<T[]> PromiseAll<T>(this IEnumerable<IPromise<T>> that) { |
|
123 | return PromiseAll(that, null); | |
|
124 | } | |
|
125 | ||
|
126 | public static IPromise<T[]> PromiseAll<T>(this IEnumerable<IPromise<T>> that, Action<T> cleanup) { | |
|
123 | 127 | Safe.ArgumentNotNull(that, "that"); |
|
124 | return PromiseAll(that.ToList()); | |
|
128 | return PromiseAll(that.ToList(), cleanup); | |
|
125 | 129 | } |
|
126 | 130 | |
|
127 | 131 | public static IPromise PromiseAll(this ICollection<IPromise> that) { |
@@ -165,16 +169,34 namespace Implab { | |||
|
165 | 169 | } |
|
166 | 170 | |
|
167 | 171 | public static IPromise<T[]> PromiseAll<T>(this ICollection<IPromise<T>> that) { |
|
172 | return PromiseAll(that, null); | |
|
173 | } | |
|
174 | ||
|
175 | /// <summary> | |
|
176 | /// Creates a new promise which will be satisfied when all promises are satisfied. | |
|
177 | /// </summary> | |
|
178 | /// <typeparam name="T"></typeparam> | |
|
179 | /// <param name="that"></param> | |
|
180 | /// <param name="cleanup">A callback used to cleanup already resolved promises in case of an error</param> | |
|
181 | /// <returns></returns> | |
|
182 | public static IPromise<T[]> PromiseAll<T>(this ICollection<IPromise<T>> that, Action<T> cleanup) { | |
|
168 | 183 | Safe.ArgumentNotNull(that, "that"); |
|
169 | 184 | |
|
170 | 185 | int count = that.Count; |
|
186 | ||
|
187 | if (count == 0) | |
|
188 | return Promise<T[]>.FromResult(new T[0]); | |
|
189 | ||
|
171 | 190 | int errors = 0; |
|
172 | 191 | var medium = new Promise<T[]>(); |
|
173 | 192 | var results = new T[that.Count]; |
|
174 | 193 | |
|
175 | 194 | medium.On(() => { |
|
176 | foreach (var p2 in that) | |
|
195 | foreach (var p2 in that) { | |
|
177 | 196 | p2.Cancel(); |
|
197 | if (cleanup != null) | |
|
198 | p2.On(cleanup); | |
|
199 | } | |
|
178 | 200 | }, PromiseEventType.ErrorOrCancel); |
|
179 | 201 | |
|
180 | 202 | int i = 0; |
@@ -414,6 +436,12 namespace Implab { | |||
|
414 | 436 | return new PromiseAwaiter<T>(that); |
|
415 | 437 | } |
|
416 | 438 | |
|
439 | public static PromiseAwaiter GetAwaiter(this IPromise that) { | |
|
440 | Safe.ArgumentNotNull(that, "that"); | |
|
441 | ||
|
442 | return new PromiseAwaiter(that); | |
|
443 | } | |
|
444 | ||
|
417 | 445 | #endif |
|
418 | 446 | } |
|
419 | 447 | } |
General Comments 3
ok, latest stable version should be in default
You need to be logged in to leave comments.
Login now