Mercurial > pub > ImplabNet
changeset 250:9f63dade3a40 v3
Working on runnable component
author | cin |
---|---|
date | Thu, 01 Feb 2018 02:43:35 +0300 |
parents | d82909310094 |
children | 7c7e9ad6fe4a |
files | Implab/Components/Disposable.cs Implab/Components/ExecutionState.cs Implab/Components/IInitializable.cs Implab/Components/IRunnable.cs Implab/Components/IServiceLocator.cs Implab/Components/RunnableComponent.cs Implab/IServiceLocator.cs Implab/Messaging/IConsumer.cs Implab/Messaging/IProducer.cs |
diffstat | 9 files changed, 105 insertions(+), 74 deletions(-) [+] |
line wrap: on
line diff
--- a/Implab/Components/Disposable.cs Wed Jan 31 11:28:38 2018 +0300 +++ b/Implab/Components/Disposable.cs Thu Feb 01 02:43:35 2018 +0300 @@ -9,15 +9,10 @@ /// </summary> public class Disposable : IDisposable { - int m_disposed; - public event EventHandler Disposed; public bool IsDisposed { - get { - Thread.MemoryBarrier(); - return m_disposed != 0; - } + get; private set; } /// <summary> @@ -25,43 +20,8 @@ /// </summary> /// <exception cref="ObjectDisposedException">The object is disposed</exception> /// <remarks> - /// Успешная проверка того, что объект не освобожден еще не гарантирует, что он не - /// будет освобожден сразу после нее, поэтому методы использующие проверку должны - /// учитывать, что объект может быть освобожден из параллельного потока. - /// Данны метод служит для упрощения отладки ошибок при использовании объекта после его - /// освобождения. - /// </remarks> - /// <example> - /// // пример синхронизированного освобождения ресурсов - /// class FileStore : Disposable { - /// readonly TextWriter m_file; - /// readonly obejct m_sync = new object(); - /// - /// public FileStore(string file) { - /// m_file = new TextWriter(File.OpenWrite(file)); - /// } - /// - /// public void Write(string text) { - /// lock(m_sync) { - /// AssertNotDisposed(); - /// m_file.Write(text); - /// } - /// } - /// - /// protected override void Dispose(bool disposing) { - /// if (disposing) - /// lock(m_sync) { - /// m_file.Dipose(); - /// base.Dispose(true); - /// } - /// else - /// base.Dispose(false); - /// } - /// } - /// <example> protected void AssertNotDisposed() { - Thread.MemoryBarrier(); - if (m_disposed != 0) + if (IsDisposed) throw new ObjectDisposedException(ToString()); } /// <summary> @@ -77,12 +37,12 @@ protected virtual void Dispose(bool disposing) { if (disposing) Disposed.DispatchEvent(this, EventArgs.Empty); - } [SuppressMessage("Microsoft.Design", "CA1063:ImplementIDisposableCorrectly", Justification = "Dipose(bool) and GC.SuppessFinalize are called")] public void Dispose() { - if (Interlocked.Increment(ref m_disposed) == 1) { + if(!IsDisposed) { + IsDisposed = true; Dispose(true); GC.SuppressFinalize(this); }
--- a/Implab/Components/ExecutionState.cs Wed Jan 31 11:28:38 2018 +0300 +++ b/Implab/Components/ExecutionState.cs Thu Feb 01 02:43:35 2018 +0300 @@ -13,12 +13,6 @@ Running, - Suspending, - - Suspended, - - Resuming, - Stopping, Failed,
--- a/Implab/Components/IInitializable.cs Wed Jan 31 11:28:38 2018 +0300 +++ b/Implab/Components/IInitializable.cs Thu Feb 01 02:43:35 2018 +0300 @@ -12,7 +12,7 @@ /// </summary> /// <remarks> /// Normally virtual methods shouldn't be called from the constructor, due to the incomplete object state, but - /// they can be called from this method. This method is aьуерщlso usefull when we constructing a complex grpah + /// they can be called from this method. This method is also usefull when we constructing a complex grpah /// of components where cyclic references may take place. /// </remarks> void Initialize();
--- a/Implab/Components/IRunnable.cs Wed Jan 31 11:28:38 2018 +0300 +++ b/Implab/Components/IRunnable.cs Thu Feb 01 02:43:35 2018 +0300 @@ -1,24 +1,23 @@ using System; +using System.Threading; +using System.Threading.Tasks; namespace Implab.Components { - /// <summary> - /// Interface for the component which performs a long running task. + /// <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 /// </summary> - IPromise Start(); + void Start(CancellationToken ct); /// <summary> - /// 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. + /// Stops this instance and releases all resources, after the instance is stopped it is moved to Disposed state and can't be reused. /// </summary> - IPromise Stop(); + void Stop(CancellationToken ct); + + Task<ExecutionState> Completion { get; } ExecutionState State { get; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Implab/Components/IServiceLocator.cs Thu Feb 01 02:43:35 2018 +0300 @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Implab.Components { + public interface IServiceLocator: IServiceProvider { + T GetService<T>(); + bool TryGetService<T>(out T service); + bool TryGetService (Type serviceType, out object service); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Implab/Components/RunnableComponent.cs Thu Feb 01 02:43:35 2018 +0300 @@ -0,0 +1,57 @@ +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace Implab.Components +{ + public class RunnableComponent : IRunnable { + + readonly object m_lock = new object(); + + CancellationTokenSource m_cts; + + public Task<ExecutionState> Completion { + get; + private set; + } + + public ExecutionState State => throw new NotImplementedException(); + + public Exception LastError => throw new NotImplementedException(); + + public event EventHandler<StateChangeEventArgs> StateChanged; + + public void Dispose() { + lock(m_lock) { + Dispose(true); + GC.SuppressFinalize(this); + } + } + + protected virtual void Dispose(bool disposing) { + if (disposing) { + Safe.Dispose(m_cts); + } + } + + public void Start(CancellationToken ct) { + lock(m_lock) { + switch (State) + { + + default: + throw new InvalidOperationException(); + } + } + } + + public void Stop(CancellationToken ct) { + throw new NotImplementedException(); + } + + protected virtual Task StartImpl(CancellationToken ct) { + + return Task.CompletedTask; + } + } +} \ No newline at end of file
--- a/Implab/IServiceLocator.cs Wed Jan 31 11:28:38 2018 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,13 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Implab { - public interface IServiceLocator: IServiceProvider { - T GetService<T>(); - bool TryGetService<T>(out T service); - bool TryGetService (Type serviceType, out object service); - } -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Implab/Messaging/IConsumer.cs Thu Feb 01 02:43:35 2018 +0300 @@ -0,0 +1,10 @@ +using System.Threading; +using System.Threading.Tasks; + +namespace Implab.Messaging { + public interface IConsumer<T> { + Task<T> Receive(CancellationToken ct); + + bool TryReceive(out T message); + } +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Implab/Messaging/IProducer.cs Thu Feb 01 02:43:35 2018 +0300 @@ -0,0 +1,11 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace Implab.Messaging { + public interface IProducer<T> { + Task PostMessageAsync(T message, CancellationToken ct); + + Task PostMessagesAsync(IEnumerable<T> messages, CancellationToken ct); + } +} \ No newline at end of file