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