@@ -1,12 +1,13 | |||||
1 | namespace Implab.Components { |
|
1 | namespace Implab.Components { | |
|
2 | ||||
2 | public enum ExecutionState { |
|
3 | public enum ExecutionState { | |
3 | Uninitialized, |
|
4 | Uninitialized, | |
4 | Initial, |
|
5 | Initial, | |
5 | Starting, |
|
6 | Starting, | |
6 | Running, |
|
7 | Running, | |
7 | Stopping, |
|
8 | Stopping, | |
8 | Stopped, |
|
9 | Stopped, | |
9 | Disposed, |
|
10 | Disposed, | |
10 | Failed |
|
11 | Failed | |
11 | } |
|
12 | } | |
12 | } No newline at end of file |
|
13 | } |
@@ -1,60 +1,75 | |||||
1 | using Implab.Parallels; |
|
1 | using Implab.Parallels; | |
2 | using System; |
|
2 | using System; | |
3 | using System.Threading; |
|
3 | using System.Threading; | |
4 |
|
4 | |||
5 | namespace Implab.Components { |
|
5 | namespace Implab.Components { | |
6 | /// <summary> |
|
6 | /// <summary> | |
7 | /// ΠΠ°Π·ΠΎΠ²ΡΠΉ ΠΊΠ»Π°ΡΡ Π΄Π»Ρ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΠΏΡΠ»ΠΎΠ² ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ². |
|
7 | /// The base class for creating object pools. | |
8 | /// </summary> |
|
8 | /// </summary> | |
9 | /// <remarks> |
|
9 | /// <remarks> | |
10 | /// <para>ΠΡΠ» ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΠΌΠ½ΠΎΠ³ΠΎΠΊΡΠ°ΡΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΎΠ΄ΠΈΠ½ ΠΈ ΡΠΎΡΠΆΠ΅ ΠΎΠ±ΡΠ΅ΠΊΡ, |
|
10 | /// <para>The objects pool is offers frequently requested objects to be reused, this gives | |
11 | /// ΡΡΠΎ Π°ΠΊΡΡΠ°Π»ΡΠ½ΠΎ Π΄Π»Ρ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ², ΡΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΊΠΎΡΠΎΡΡΡ ΡΡΠ΅Π±ΡΠ΅Ρ ΡΡΡΠ΅ΡΡΠ²Π΅Π½Π½ΡΡ ΡΠ΅ΡΡΡΡΠΎΠ². |
|
11 | /// a gool speed improvement for the 'heavy' objects. To avoid memory overhead the pool uses | |
12 | /// ΠΡΠ» ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ ΡΠ»Π°Π±ΡΠ΅ ΡΡΡΠ»ΠΊΠΈ, ΡΡΠΎΠ±Ρ Π½Π΅ ΠΏΡΠ΅ΠΏΡΡΡΡΠ²ΠΎΠ²Π°ΡΡ ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π΅Π½ΠΈΡ |
|
12 | /// weak references allowing CG to do it's work. If there are no free objects in the pool | |
13 | /// ΡΠ΅ΡΡΡΡΠΎΠ² ΠΈ ΡΠΎΠ·Π΄Π°Π΅Ρ Π½ΠΎΠ²ΡΠ΅ ΠΎΠ±ΡΠ΅ΠΊΡΡ ΠΏΡΠΈ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΡΠΈ.</para> |
|
13 | /// they are created on demand. </para> | |
14 | /// <para> |
|
14 | /// <para> | |
15 | /// ΠΠ°ΡΠ»Π΅Π΄Π½ΠΈΠΊΠΈ Π΄ΠΎΠ»ΠΆΠ½Ρ ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²ΡΠ²Π°ΡΡ ΠΌΠ΅ΡΠΎΠ΄ <see cref="CreateInstance()"/> Π΄Π»Ρ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ |
|
15 | /// Implementors need to defined a <see cref="CreateInstance()"/> method | |
16 | /// Π½ΠΎΠ²ΡΡ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠΎΠ². |
|
|||
17 | /// </para> |
|
16 | /// </para> | |
18 | /// <para>ΠΡΠ» ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅Ρ ΠΎΠ±ΡΠ°ΡΠ΅Π½ΠΈΡ ΡΡΠ°Π·Ρ ΠΈΠ· Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΡ ΠΏΠΎΡΠΎΠΊΠΎΠ².</para> |
|
17 | /// <para>The instances of this class are thred-safe.</para> | |
19 | /// </remarks> |
|
18 | /// </remarks> | |
20 | public abstract class ObjectPool<T> where T : class { |
|
19 | public abstract class ObjectPool<T> where T : class { | |
21 | readonly AsyncQueue<WeakReference> m_queue = new AsyncQueue<WeakReference>(); |
|
20 | readonly AsyncQueue<WeakReference> m_queue = new AsyncQueue<WeakReference>(); | |
22 | readonly int m_size; |
|
21 | readonly int m_size; | |
23 | int m_count = 0; |
|
22 | int m_count = 0; | |
24 |
|
23 | |||
25 | protected ObjectPool() : this(Environment.ProcessorCount+1) { |
|
24 | protected ObjectPool() : this(Environment.ProcessorCount+1) { | |
26 |
|
25 | |||
27 | } |
|
26 | } | |
28 |
|
27 | |||
29 | protected ObjectPool(int size) { |
|
28 | protected ObjectPool(int size) { | |
30 | Safe.ArgumentInRange(size,1,size,"size"); |
|
29 | Safe.ArgumentInRange(size,1,size,"size"); | |
31 |
|
30 | |||
32 | m_size = size; |
|
31 | m_size = size; | |
33 | } |
|
32 | } | |
34 |
|
33 | |||
|
34 | /// <summary> | |||
|
35 | /// Creates the instance if there are no free ones in the pool. | |||
|
36 | /// </summary> | |||
|
37 | /// <returns>The new instance.</returns> | |||
35 | protected abstract T CreateInstance(); |
|
38 | protected abstract T CreateInstance(); | |
36 |
|
39 | |||
|
40 | /// <summary> | |||
|
41 | /// Cleanups the instance. | |||
|
42 | /// </summary> | |||
|
43 | /// <param name="instance">The instance to cleanup and prepare it for the next use.</param> | |||
37 | protected virtual void CleanupInstance(T instance) { |
|
44 | protected virtual void CleanupInstance(T instance) { | |
38 | } |
|
45 | } | |
39 |
|
46 | |||
|
47 | /// <summary> | |||
|
48 | /// Allocate free instance from the pool or reates a new one. | |||
|
49 | /// </summary> | |||
40 | public T Allocate() { |
|
50 | public T Allocate() { | |
41 | WeakReference reference; |
|
51 | WeakReference reference; | |
42 | while (m_queue.TryDequeue(out reference)) { |
|
52 | while (m_queue.TryDequeue(out reference)) { | |
43 | Interlocked.Decrement(ref m_count); |
|
53 | Interlocked.Decrement(ref m_count); | |
44 | object instance = reference.Target; |
|
54 | object instance = reference.Target; | |
45 | if (instance == null) |
|
55 | if (instance == null) | |
46 | continue; |
|
56 | continue; | |
47 | return (T)instance; |
|
57 | return (T)instance; | |
48 | } |
|
58 | } | |
49 | return CreateInstance(); |
|
59 | return CreateInstance(); | |
50 | } |
|
60 | } | |
51 |
|
61 | |||
|
62 | /// <summary> | |||
|
63 | /// Release the specified instance and returns it to the pool of free instances. | |||
|
64 | /// </summary> | |||
|
65 | /// <param name="instance">The instance to return to the pool.</param> | |||
|
66 | /// <remarks>Before the instance is returned to the pool the <see cref="CleanupInstance(T)"/> is called.</remarks> | |||
52 | public void Release(T instance) { |
|
67 | public void Release(T instance) { | |
53 | if (m_count < m_size && instance != null) { |
|
68 | if (m_count < m_size && instance != null) { | |
54 | Interlocked.Increment(ref m_count); |
|
69 | Interlocked.Increment(ref m_count); | |
55 | CleanupInstance(instance); |
|
70 | CleanupInstance(instance); | |
56 | m_queue.Enqueue(new WeakReference(instance)); |
|
71 | m_queue.Enqueue(new WeakReference(instance)); | |
57 | } |
|
72 | } | |
58 | } |
|
73 | } | |
59 | } |
|
74 | } | |
60 | } |
|
75 | } |
General Comments 0
You need to be logged in to leave comments.
Login now