diff --git a/Implab/Components/Disposable.cs b/Implab/Components/Disposable.cs
--- a/Implab/Components/Disposable.cs
+++ b/Implab/Components/Disposable.cs
@@ -9,15 +9,10 @@ namespace Implab.Components {
///
public class Disposable : IDisposable {
- int m_disposed;
-
public event EventHandler Disposed;
public bool IsDisposed {
- get {
- Thread.MemoryBarrier();
- return m_disposed != 0;
- }
+ get; private set;
}
///
@@ -25,43 +20,8 @@ namespace Implab.Components {
///
/// The object is disposed
///
- /// Успешная проверка того, что объект не освобожден еще не гарантирует, что он не
- /// будет освобожден сразу после нее, поэтому методы использующие проверку должны
- /// учитывать, что объект может быть освобожден из параллельного потока.
- /// Данны метод служит для упрощения отладки ошибок при использовании объекта после его
- /// освобождения.
- ///
- ///
- /// // пример синхронизированного освобождения ресурсов
- /// 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);
- /// }
- /// }
- ///
protected void AssertNotDisposed() {
- Thread.MemoryBarrier();
- if (m_disposed != 0)
+ if (IsDisposed)
throw new ObjectDisposedException(ToString());
}
///
@@ -77,12 +37,12 @@ namespace Implab.Components {
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);
}
diff --git a/Implab/Components/ExecutionState.cs b/Implab/Components/ExecutionState.cs
--- a/Implab/Components/ExecutionState.cs
+++ b/Implab/Components/ExecutionState.cs
@@ -13,12 +13,6 @@
Running,
- Suspending,
-
- Suspended,
-
- Resuming,
-
Stopping,
Failed,
diff --git a/Implab/Components/IInitializable.cs b/Implab/Components/IInitializable.cs
--- a/Implab/Components/IInitializable.cs
+++ b/Implab/Components/IInitializable.cs
@@ -12,7 +12,7 @@ namespace Implab.Components {
///
///
/// 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.
///
void Initialize();
diff --git a/Implab/Components/IRunnable.cs b/Implab/Components/IRunnable.cs
--- a/Implab/Components/IRunnable.cs
+++ b/Implab/Components/IRunnable.cs
@@ -1,24 +1,23 @@
using System;
+using System.Threading;
+using System.Threading.Tasks;
namespace Implab.Components {
- ///
- /// Interface for the component which performs a long running task.
+ ///
+ /// Interface for the component which performs a long running task.
///
- ///
- /// The component also should implement interface to be able to release used resources.
- /// 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.
- ///
public interface IRunnable : IDisposable {
///
/// Starts this instance
///
- IPromise Start();
+ void Start(CancellationToken ct);
///
- /// 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.
///
- IPromise Stop();
+ void Stop(CancellationToken ct);
+
+ Task Completion { get; }
ExecutionState State { get; }
diff --git a/Implab/Components/IServiceLocator.cs b/Implab/Components/IServiceLocator.cs
new file mode 100644
--- /dev/null
+++ b/Implab/Components/IServiceLocator.cs
@@ -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();
+ bool TryGetService(out T service);
+ bool TryGetService (Type serviceType, out object service);
+ }
+}
diff --git a/Implab/Components/RunnableComponent.cs b/Implab/Components/RunnableComponent.cs
new file mode 100644
--- /dev/null
+++ b/Implab/Components/RunnableComponent.cs
@@ -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 Completion {
+ get;
+ private set;
+ }
+
+ public ExecutionState State => throw new NotImplementedException();
+
+ public Exception LastError => throw new NotImplementedException();
+
+ public event EventHandler 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
diff --git a/Implab/IServiceLocator.cs b/Implab/IServiceLocator.cs
deleted file mode 100644
--- a/Implab/IServiceLocator.cs
+++ /dev/null
@@ -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();
- bool TryGetService(out T service);
- bool TryGetService (Type serviceType, out object service);
- }
-}
diff --git a/Implab/Messaging/IConsumer.cs b/Implab/Messaging/IConsumer.cs
new file mode 100644
--- /dev/null
+++ b/Implab/Messaging/IConsumer.cs
@@ -0,0 +1,10 @@
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Implab.Messaging {
+ public interface IConsumer {
+ Task Receive(CancellationToken ct);
+
+ bool TryReceive(out T message);
+ }
+}
\ No newline at end of file
diff --git a/Implab/Messaging/IProducer.cs b/Implab/Messaging/IProducer.cs
new file mode 100644
--- /dev/null
+++ b/Implab/Messaging/IProducer.cs
@@ -0,0 +1,11 @@
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Implab.Messaging {
+ public interface IProducer {
+ Task PostMessageAsync(T message, CancellationToken ct);
+
+ Task PostMessagesAsync(IEnumerable messages, CancellationToken ct);
+ }
+}
\ No newline at end of file