Mercurial > pub > ImplabNet
changeset 208:7d07503621fe v2
RunnableComponent.Dispose(bool,Exception) changed to standart Dispose(bool)
IRunnable is now disposable
Code cleanups, suppressed some CodeAnalysis warnings
author | cin |
---|---|
date | Sun, 13 Nov 2016 18:28:17 +0300 |
parents | 558f34b2fb50 |
children | a867536c68fc |
files | Implab.Test/Mock/MockRunnableComponent.cs Implab.Test/RunnableComponentTests.cs Implab/Components/Disposable.cs Implab/Components/IRunnable.cs Implab/Components/PollingComponent.cs Implab/Components/RunnableComponent.cs Implab/Formats/JSON/JSONParser.cs Implab/Formats/JSON/JSONScanner.cs Implab/PromiseExtensions.cs |
diffstat | 9 files changed, 66 insertions(+), 37 deletions(-) [+] |
line wrap: on
line diff
--- a/Implab.Test/Mock/MockRunnableComponent.cs Wed Nov 09 12:03:22 2016 +0300 +++ b/Implab.Test/Mock/MockRunnableComponent.cs Sun Nov 13 18:28:17 2016 +0300 @@ -24,7 +24,7 @@ set; } - public Action<bool, Exception> MockDispose { + public Action<bool> MockDispose { get; set; } @@ -42,10 +42,10 @@ MockInit(); } - protected override void Dispose(bool disposing, Exception lastError) { + protected override void Dispose(bool disposing) { if (MockDispose != null) - MockDispose(disposing, lastError); - base.Dispose(disposing, lastError); + MockDispose(disposing); + base.Dispose(disposing); } } }
--- a/Implab.Test/RunnableComponentTests.cs Wed Nov 09 12:03:22 2016 +0300 +++ b/Implab.Test/RunnableComponentTests.cs Sun Nov 13 18:28:17 2016 +0300 @@ -95,7 +95,7 @@ var comp = new MockRunnableComponent(true); bool disposed = false; - comp.MockDispose = (disposing, error) => { + comp.MockDispose = (disposing) => { disposed = true; }; @@ -115,7 +115,7 @@ var comp = new MockRunnableComponent(true, true); bool disposed = false; - comp.MockDispose = (disposing, error) => { + comp.MockDispose = (disposing) => { disposed = true; }; @@ -131,10 +131,8 @@ var comp = new MockRunnableComponent(true, true); bool disposed = false; - Exception lastError = null; - comp.MockDispose = (disposing, error) => { + comp.MockDispose = (disposing) => { disposed = true; - lastError = error; }; comp.Start().Join(1000);
--- a/Implab/Components/Disposable.cs Wed Nov 09 12:03:22 2016 +0300 +++ b/Implab/Components/Disposable.cs Sun Nov 13 18:28:17 2016 +0300 @@ -1,5 +1,6 @@ using Implab.Diagnostics; using System; +using System.Diagnostics.CodeAnalysis; using System.Threading; namespace Implab.Components { @@ -81,6 +82,7 @@ } } + [SuppressMessage("Microsoft.Design", "CA1063:ImplementIDisposableCorrectly", Justification = "Dipose(bool) and GC.SuppessFinalize are called")] public void Dispose() { if (Interlocked.Increment(ref m_disposed) == 1) { Dispose(true);
--- a/Implab/Components/IRunnable.cs Wed Nov 09 12:03:22 2016 +0300 +++ b/Implab/Components/IRunnable.cs Sun Nov 13 18:28:17 2016 +0300 @@ -1,14 +1,22 @@ using System; namespace Implab.Components { - public interface IRunnable { + /// <summary> + /// Interface for the component which performs a long running task. + /// </summary> + /// <remarks> + /// <para>The component also should implement <see cref="IDisposable"/> interface to be able to release used resources.</para> + /// <para>All methods of this interface must be a thread safe. If the operation is not applicable in the current state the + /// method should throw an exception and keep the current state unchanged.</para> + /// </remarks> + public interface IRunnable : IDisposable { /// <summary> - /// Starts this instance. + /// Starts this instance /// </summary> IPromise Start(); /// <summary> - /// Stops this instance. After the instance is stopped it can't be started again, stopping should be treated as gracefull and async dispose. + /// 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. /// </summary> IPromise Stop();
--- a/Implab/Components/PollingComponent.cs Wed Nov 09 12:03:22 2016 +0300 +++ b/Implab/Components/PollingComponent.cs Sun Nov 13 18:28:17 2016 +0300 @@ -144,11 +144,11 @@ return base.OnStop(); } - protected override void Dispose(bool disposing, Exception lastError) { + protected override void Dispose(bool disposing) { if (disposing) - Safe.Dispose(m_timer); + m_timer.Dispose(); - base.Dispose(disposing, lastError); + base.Dispose(disposing); } } }
--- a/Implab/Components/RunnableComponent.cs Wed Nov 09 12:03:22 2016 +0300 +++ b/Implab/Components/RunnableComponent.cs Sun Nov 13 18:28:17 2016 +0300 @@ -1,5 +1,6 @@ using System; - +using System.Diagnostics.CodeAnalysis; + namespace Implab.Components { public abstract class RunnableComponent : IDisposable, IRunnable, IInitializable { enum Commands { @@ -333,30 +334,22 @@ /// especially if <see cref="Stop"/> method is failed. Using this method insted of <see cref="Stop()"/> may /// lead to the data loss by the component. /// </para></remarks> + [SuppressMessage("Microsoft.Design", "CA1063:ImplementIDisposableCorrectly", Justification = "Dipose(bool) and GC.SuppessFinalize are called")] public void Dispose() { IPromise pending; lock (m_stateMachine) { if (m_stateMachine.State == ExecutionState.Disposed) return; - pending = Move(Commands.Dispose, null, null); + Move(Commands.Dispose, null, null); } GC.SuppressFinalize(this); - if (pending != null) { - pending.Cancel(); - pending.Timeout(DisposeTimeout).On( - () => Dispose(true, null), - err => Dispose(true, err), - reason => Dispose(true, new OperationCanceledException("The operation is cancelled", reason)) - ); - } else { - Dispose(true, null); - } + Dispose(true); } ~RunnableComponent() { - Dispose(false, null); + Dispose(false); } #endregion @@ -365,8 +358,8 @@ /// Releases all resources used by the component, called automatically, override this method to implement your cleanup. /// </summary> /// <param name="disposing">true if this method is called during normal dispose process.</param> - /// <param name="lastError">The last error which occured during the component stop.</param> - protected virtual void Dispose(bool disposing, Exception lastError) { + /// <param name="pending">The operation which is currenty pending</param> + protected virtual void Dispose(bool disposing) { }
--- a/Implab/Formats/JSON/JSONParser.cs Wed Nov 09 12:03:22 2016 +0300 +++ b/Implab/Formats/JSON/JSONParser.cs Sun Nov 13 18:28:17 2016 +0300 @@ -274,7 +274,7 @@ protected override void Dispose(bool disposing) { if (disposing) - Safe.Dispose(m_scanner); + m_scanner.Dispose(); } /// <summary>
--- a/Implab/Formats/JSON/JSONScanner.cs Wed Nov 09 12:03:22 2016 +0300 +++ b/Implab/Formats/JSON/JSONScanner.cs Sun Nov 13 18:28:17 2016 +0300 @@ -102,7 +102,7 @@ protected override void Dispose(bool disposing) { if (disposing) - Safe.Dispose(m_scanner); + m_scanner.Dispose(); base.Dispose(disposing); } }
--- a/Implab/PromiseExtensions.cs Wed Nov 09 12:03:22 2016 +0300 +++ b/Implab/PromiseExtensions.cs Sun Nov 13 18:28:17 2016 +0300 @@ -120,8 +120,12 @@ } public static IPromise<T[]> PromiseAll<T>(this IEnumerable<IPromise<T>> that) { + return PromiseAll(that, null); + } + + public static IPromise<T[]> PromiseAll<T>(this IEnumerable<IPromise<T>> that, Action<T> cleanup) { Safe.ArgumentNotNull(that, "that"); - return PromiseAll(that.ToList()); + return PromiseAll(that.ToList(), cleanup); } public static IPromise PromiseAll(this ICollection<IPromise> that) { @@ -164,17 +168,35 @@ return medium; } - public static IPromise<T[]> PromiseAll<T>(this ICollection<IPromise<T>> that) { + public static IPromise<T[]> PromiseAll<T>(this ICollection<IPromise<T>> that) { + return PromiseAll(that, null); + } + + /// <summary> + /// Creates a new promise which will be satisfied when all promises are satisfied. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="that"></param> + /// <param name="cleanup">A callback used to cleanup already resolved promises in case of an error</param> + /// <returns></returns> + public static IPromise<T[]> PromiseAll<T>(this ICollection<IPromise<T>> that, Action<T> cleanup) { Safe.ArgumentNotNull(that, "that"); + + int count = that.Count; - int count = that.Count; + if (count == 0) + return Promise<T[]>.FromResult(new T[0]); + int errors = 0; var medium = new Promise<T[]>(); var results = new T[that.Count]; medium.On(() => { - foreach (var p2 in that) - p2.Cancel(); + foreach (var p2 in that) { + p2.Cancel(); + if (cleanup != null) + p2.On(cleanup); + } }, PromiseEventType.ErrorOrCancel); int i = 0; @@ -414,6 +436,12 @@ return new PromiseAwaiter<T>(that); } + public static PromiseAwaiter GetAwaiter(this IPromise that) { + Safe.ArgumentNotNull(that, "that"); + + return new PromiseAwaiter(that); + } + #endif } }