Auto status change to "Under Review"
@@ -0,0 +1,13 | |||
|
1 | using System; | |
|
2 | using System.Collections.Generic; | |
|
3 | using System.Linq; | |
|
4 | using System.Text; | |
|
5 | using System.Threading.Tasks; | |
|
6 | ||
|
7 | namespace Implab.Components { | |
|
8 | public interface IServiceLocator: IServiceProvider { | |
|
9 | T GetService<T>(); | |
|
10 | bool TryGetService<T>(out T service); | |
|
11 | bool TryGetService (Type serviceType, out object service); | |
|
12 | } | |
|
13 | } |
@@ -0,0 +1,57 | |||
|
1 | using System; | |
|
2 | using System.Threading; | |
|
3 | using System.Threading.Tasks; | |
|
4 | ||
|
5 | namespace Implab.Components | |
|
6 | { | |
|
7 | public class RunnableComponent : IRunnable { | |
|
8 | ||
|
9 | readonly object m_lock = new object(); | |
|
10 | ||
|
11 | CancellationTokenSource m_cts; | |
|
12 | ||
|
13 | public Task<ExecutionState> Completion { | |
|
14 | get; | |
|
15 | private set; | |
|
16 | } | |
|
17 | ||
|
18 | public ExecutionState State => throw new NotImplementedException(); | |
|
19 | ||
|
20 | public Exception LastError => throw new NotImplementedException(); | |
|
21 | ||
|
22 | public event EventHandler<StateChangeEventArgs> StateChanged; | |
|
23 | ||
|
24 | public void Dispose() { | |
|
25 | lock(m_lock) { | |
|
26 | Dispose(true); | |
|
27 | GC.SuppressFinalize(this); | |
|
28 | } | |
|
29 | } | |
|
30 | ||
|
31 | protected virtual void Dispose(bool disposing) { | |
|
32 | if (disposing) { | |
|
33 | Safe.Dispose(m_cts); | |
|
34 | } | |
|
35 | } | |
|
36 | ||
|
37 | public void Start(CancellationToken ct) { | |
|
38 | lock(m_lock) { | |
|
39 | switch (State) | |
|
40 | { | |
|
41 | ||
|
42 | default: | |
|
43 | throw new InvalidOperationException(); | |
|
44 | } | |
|
45 | } | |
|
46 | } | |
|
47 | ||
|
48 | public void Stop(CancellationToken ct) { | |
|
49 | throw new NotImplementedException(); | |
|
50 | } | |
|
51 | ||
|
52 | protected virtual Task StartImpl(CancellationToken ct) { | |
|
53 | ||
|
54 | return Task.CompletedTask; | |
|
55 | } | |
|
56 | } | |
|
57 | } No newline at end of file |
@@ -0,0 +1,10 | |||
|
1 | using System.Threading; | |
|
2 | using System.Threading.Tasks; | |
|
3 | ||
|
4 | namespace Implab.Messaging { | |
|
5 | public interface IConsumer<T> { | |
|
6 | Task<T> Receive(CancellationToken ct); | |
|
7 | ||
|
8 | bool TryReceive(out T message); | |
|
9 | } | |
|
10 | } No newline at end of file |
@@ -0,0 +1,11 | |||
|
1 | using System.Collections.Generic; | |
|
2 | using System.Threading; | |
|
3 | using System.Threading.Tasks; | |
|
4 | ||
|
5 | namespace Implab.Messaging { | |
|
6 | public interface IProducer<T> { | |
|
7 | Task PostMessageAsync(T message, CancellationToken ct); | |
|
8 | ||
|
9 | Task PostMessagesAsync(IEnumerable<T> messages, CancellationToken ct); | |
|
10 | } | |
|
11 | } No newline at end of file |
@@ -9,15 +9,10 namespace Implab.Components { | |||
|
9 | 9 | /// </summary> |
|
10 | 10 | public class Disposable : IDisposable { |
|
11 | 11 | |
|
12 | int m_disposed; | |
|
13 | ||
|
14 | 12 | public event EventHandler Disposed; |
|
15 | 13 | |
|
16 | 14 | public bool IsDisposed { |
|
17 |
get |
|
|
18 | Thread.MemoryBarrier(); | |
|
19 | return m_disposed != 0; | |
|
20 | } | |
|
15 | get; private set; | |
|
21 | 16 | } |
|
22 | 17 | |
|
23 | 18 | /// <summary> |
@@ -25,43 +20,8 namespace Implab.Components { | |||
|
25 | 20 | /// </summary> |
|
26 | 21 | /// <exception cref="ObjectDisposedException">The object is disposed</exception> |
|
27 | 22 | /// <remarks> |
|
28 | /// Успешная проверка того, что объект не освобожден еще не гарантирует, что он не | |
|
29 | /// будет освобожден сразу после нее, поэтому методы использующие проверку должны | |
|
30 | /// учитывать, что объект может быть освобожден из параллельного потока. | |
|
31 | /// Данны метод служит для упрощения отладки ошибок при использовании объекта после его | |
|
32 | /// освобождения. | |
|
33 | /// </remarks> | |
|
34 | /// <example> | |
|
35 | /// // пример синхронизированного освобождения ресурсов | |
|
36 | /// class FileStore : Disposable { | |
|
37 | /// readonly TextWriter m_file; | |
|
38 | /// readonly obejct m_sync = new object(); | |
|
39 | /// | |
|
40 | /// public FileStore(string file) { | |
|
41 | /// m_file = new TextWriter(File.OpenWrite(file)); | |
|
42 | /// } | |
|
43 | /// | |
|
44 | /// public void Write(string text) { | |
|
45 | /// lock(m_sync) { | |
|
46 | /// AssertNotDisposed(); | |
|
47 | /// m_file.Write(text); | |
|
48 | /// } | |
|
49 | /// } | |
|
50 | /// | |
|
51 | /// protected override void Dispose(bool disposing) { | |
|
52 | /// if (disposing) | |
|
53 | /// lock(m_sync) { | |
|
54 | /// m_file.Dipose(); | |
|
55 | /// base.Dispose(true); | |
|
56 | /// } | |
|
57 | /// else | |
|
58 | /// base.Dispose(false); | |
|
59 | /// } | |
|
60 | /// } | |
|
61 | /// <example> | |
|
62 | 23 | protected void AssertNotDisposed() { |
|
63 | Thread.MemoryBarrier(); | |
|
64 | if (m_disposed != 0) | |
|
24 | if (IsDisposed) | |
|
65 | 25 | throw new ObjectDisposedException(ToString()); |
|
66 | 26 | } |
|
67 | 27 | /// <summary> |
@@ -77,12 +37,12 namespace Implab.Components { | |||
|
77 | 37 | protected virtual void Dispose(bool disposing) { |
|
78 | 38 | if (disposing) |
|
79 | 39 | Disposed.DispatchEvent(this, EventArgs.Empty); |
|
80 | ||
|
81 | 40 | } |
|
82 | 41 | |
|
83 | 42 | [SuppressMessage("Microsoft.Design", "CA1063:ImplementIDisposableCorrectly", Justification = "Dipose(bool) and GC.SuppessFinalize are called")] |
|
84 | 43 | public void Dispose() { |
|
85 | if (Interlocked.Increment(ref m_disposed) == 1) { | |
|
44 | if(!IsDisposed) { | |
|
45 | IsDisposed = true; | |
|
86 | 46 | Dispose(true); |
|
87 | 47 | GC.SuppressFinalize(this); |
|
88 | 48 | } |
@@ -13,12 +13,6 | |||
|
13 | 13 | |
|
14 | 14 | Running, |
|
15 | 15 | |
|
16 | Suspending, | |
|
17 | ||
|
18 | Suspended, | |
|
19 | ||
|
20 | Resuming, | |
|
21 | ||
|
22 | 16 | Stopping, |
|
23 | 17 | |
|
24 | 18 | Failed, |
@@ -12,7 +12,7 namespace Implab.Components { | |||
|
12 | 12 | /// </summary> |
|
13 | 13 | /// <remarks> |
|
14 | 14 | /// Normally virtual methods shouldn't be called from the constructor, due to the incomplete object state, but |
|
15 |
/// they can be called from this method. This method is a |
|
|
15 | /// they can be called from this method. This method is also usefull when we constructing a complex grpah | |
|
16 | 16 | /// of components where cyclic references may take place. |
|
17 | 17 | /// </remarks> |
|
18 | 18 | void Initialize(); |
@@ -1,24 +1,23 | |||
|
1 | 1 | using System; |
|
2 | using System.Threading; | |
|
3 | using System.Threading.Tasks; | |
|
2 | 4 | |
|
3 | 5 | namespace Implab.Components { |
|
4 | 6 | /// <summary> |
|
5 | 7 | /// Interface for the component which performs a long running task. |
|
6 | 8 | /// </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 | 9 | public interface IRunnable : IDisposable { |
|
13 | 10 | /// <summary> |
|
14 | 11 | /// Starts this instance |
|
15 | 12 | /// </summary> |
|
16 | IPromise Start(); | |
|
13 | void Start(CancellationToken ct); | |
|
17 | 14 | |
|
18 | 15 | /// <summary> |
|
19 |
/// Stops this instance, after the instance is stopped it |
|
|
16 | /// Stops this instance and releases all resources, after the instance is stopped it is moved to Disposed state and can't be reused. | |
|
20 | 17 | /// </summary> |
|
21 | IPromise Stop(); | |
|
18 | void Stop(CancellationToken ct); | |
|
19 | ||
|
20 | Task<ExecutionState> Completion { get; } | |
|
22 | 21 | |
|
23 | 22 | ExecutionState State { get; } |
|
24 | 23 |
|
1 | NO CONTENT: file was removed |
General Comments 3
ok, latest stable version should be in default
You need to be logged in to leave comments.
Login now