##// END OF EJS Templates
docs
cin -
r153:b933ec88446e v2
parent child
Show More
@@ -1,20 +1,25
1 using System;
1 using System;
2 using System.Collections.Generic;
2 using System.Collections.Generic;
3
3
4 namespace Implab.Components {
4 namespace Implab.Components {
5 /// <summary>
5 /// <summary>
6 /// Global application components and services.
6 /// Global application components and services.
7 /// </summary>
7 /// </summary>
8 public static class App {
8 public static class App {
9 readonly static ComponentContainer<object> _root = new ComponentContainer<object>();
9 readonly static ComponentContainer<object> _root = new ComponentContainer<object>();
10
10
11 /// <summary>
12 /// The container for application level components.
13 /// </summary>
14 /// <remarks>Pools of disposable objects can be placed here and they will be automatically
15 /// disposed when application domain is unloaded.</remarks>
11 public static ICollection<object> RootContainer {
16 public static ICollection<object> RootContainer {
12 get { return _root; }
17 get { return _root; }
13 }
18 }
14
19
15 static App() {
20 static App() {
16 AppDomain.CurrentDomain.ProcessExit += (sender, e) => _root.Dispose();
21 AppDomain.CurrentDomain.DomainUnload += (sender, e) => _root.Dispose();
17 }
22 }
18 }
23 }
19 }
24 }
20
25
@@ -1,84 +1,127
1 using System;
1 using System;
2 using System.Collections.Generic;
2 using System.Collections.Generic;
3 using System.Linq;
3 using System.Linq;
4
4
5 namespace Implab.Components {
5 namespace Implab.Components {
6 /// <summary>
6 /// <summary>
7 /// Component container.
7 /// Component container, used to store track components in multi-threaded environmment.
8 /// </summary>
8 /// </summary>
9 /// <remarks>Instanses of this class are thread safe.</remarks>
9 /// <remarks>Instanses of this class are thread safe.</remarks>
10 public class ComponentContainer<T> : Disposable, ICollection<T> {
10 public class ComponentContainer<T> : Disposable, ICollection<T> {
11 readonly HashSet<T> m_components = new HashSet<T>();
11 readonly HashSet<T> m_components = new HashSet<T>();
12
12
13 /// <summary>
14 /// Removes currently stored compoenents from the container and disposes them if possible.
15 /// </summary>
16 /// <remarks>
17 /// A new components may be added before this method completes.
18 /// </remarks>
13 public void Clear() {
19 public void Clear() {
14 T[] removed;
20 T[] removed;
15
21
16 lock (m_components) {
22 lock (m_components) {
17 removed = new T[m_components.Count];
23 removed = new T[m_components.Count];
18 m_components.CopyTo(removed);
24 m_components.CopyTo(removed);
19 m_components.Clear();
25 m_components.Clear();
20 }
26 }
21
27
22 foreach (var item in removed.OfType<IDisposable>())
28 foreach (var item in removed.OfType<IDisposable>())
23 item.Dispose();
29 item.Dispose();
24 }
30 }
25
31
32 /// <summary>
33 /// Checks whether the specified item in the collection.
34 /// </summary>
35 /// <param name="item">The item to check.</param>
26 public bool Contains(T item) {
36 public bool Contains(T item) {
27 lock (m_components)
37 lock (m_components)
28 return m_components.Contains(item);
38 return m_components.Contains(item);
29 }
39 }
30
40
41 /// <summary>
42 /// Copies currently stored components to the specified array.
43 /// </summary>
44 /// <param name="array">A destination array for components.</param>
45 /// <param name="arrayIndex">A starting index in the destination array.</param>
31 public void CopyTo(T[] array, int arrayIndex) {
46 public void CopyTo(T[] array, int arrayIndex) {
32 lock (m_components)
47 lock (m_components)
33 m_components.CopyTo(array, arrayIndex);
48 m_components.CopyTo(array, arrayIndex);
34 }
49 }
35
50
51 /// <summary>
52 /// Remove the specified item from the collection.
53 /// </summary>
54 /// <param name="item">The item to remove.</param>
36 public bool Remove(T item) {
55 public bool Remove(T item) {
37 lock (m_components)
56 lock (m_components)
38 return m_components.Remove(item);
57 return m_components.Remove(item);
39 }
58 }
40
59
60 /// <summary>
61 /// Gets the count of components in the collection.
62 /// </summary>
41 public int Count {
63 public int Count {
42 get {
64 get {
43 lock (m_components)
65 lock (m_components)
44 return m_components.Count;
66 return m_components.Count;
45 }
67 }
46 }
68 }
47
69
70 /// <summary>
71 /// Gets a value indicating whether this instance is read only.
72 /// </summary>
73 /// <remarks>
74 /// Always false.
75 /// </remarks>
48 public bool IsReadOnly {
76 public bool IsReadOnly {
49 get {
77 get {
50 return false;
78 return false;
51 }
79 }
52 }
80 }
53
81
82 /// <summary>
83 /// Gets the enumerator for components in the collection.
84 /// </summary>
85 /// <returns>The enumerator.</returns>
54 public IEnumerator<T> GetEnumerator() {
86 public IEnumerator<T> GetEnumerator() {
55 T[] items;
87 T[] items;
56 lock (m_components) {
88 lock (m_components) {
57 items = new T[m_components.Count];
89 items = new T[m_components.Count];
58 m_components.CopyTo(items);
90 m_components.CopyTo(items);
59 return (IEnumerator<T>)items.GetEnumerator();
91 return (IEnumerator<T>)items.GetEnumerator();
60 }
92 }
61 }
93 }
62
94
63 System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
95 System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
64 return GetEnumerator();
96 return GetEnumerator();
65 }
97 }
66
98
99 /// <summary>
100 /// Add the specified item to the collection.
101 /// </summary>
102 /// <param name="item">The item to add.</param>
103 /// <remarks>
104 /// If the collection is alredy disposed, the item isn't added to the collection and disposed if possible.
105 /// </remarks>
67 public void Add(T item) {
106 public void Add(T item) {
68 Safe.ArgumentNotNull(item, "item");
107 Safe.ArgumentNotNull(item, "item");
69
108
70 lock (m_components) {
109 lock (m_components) {
71 if (IsDisposed)
110 if (IsDisposed)
72 Safe.Dispose(item);
111 Safe.Dispose(item);
73 else
112 else
74 m_components.Add(item);
113 m_components.Add(item);
75 }
114 }
76 }
115 }
77
116
117 /// <summary>
118 /// Disposes the components stored in the collection.
119 /// </summary>
120 /// <param name="disposing">If set to <c>true</c> the collection is disposing.</param>
78 protected override void Dispose(bool disposing) {
121 protected override void Dispose(bool disposing) {
79 base.Dispose(disposing);
122 base.Dispose(disposing);
80 Clear();
123 Clear();
81 }
124 }
82 }
125 }
83 }
126 }
84
127
@@ -1,90 +1,102
1 using System;
1 using System;
2 using Implab.Parallels;
2 using Implab.Parallels;
3 using System.Threading;
3 using System.Threading;
4 using System.Diagnostics;
4 using System.Diagnostics;
5 using System.Diagnostics.CodeAnalysis;
5 using System.Diagnostics.CodeAnalysis;
6
6
7 namespace Implab {
7 namespace Implab.Components {
8 /// <summary>
9 /// The base class for implementing pools of disposable objects.
10 /// </summary>
11 /// <remarks>
12 /// <para>This class maintains a set of pre-created objects and which are frequently allocated and released
13 /// by clients. The pool maintains maximum number of unsued object, any object above this limit is disposed,
14 /// if the pool is empty it will create new objects on demand.</para>
15 /// <para>Instances of this class are thread-safe.</para>
16 /// </remarks>
8 public abstract class DisposablePool<T> : IDisposable {
17 public abstract class DisposablePool<T> : IDisposable {
9 readonly int m_size;
18 readonly int m_size;
10 readonly AsyncQueue<T> m_queue = new AsyncQueue<T>();
19 readonly AsyncQueue<T> m_queue = new AsyncQueue<T>();
11
20
12 [SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes")]
21 [SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes")]
13 static readonly bool _isValueType = typeof(T).IsValueType;
22 static readonly bool _isValueType = typeof(T).IsValueType;
14
23
15 bool m_disposed;
24 bool m_disposed;
16
25
17 int m_count;
26 int m_count;
18
27
19 protected DisposablePool(int size) {
28 protected DisposablePool(int size) {
20 m_size = size;
29 m_size = size;
21 }
30 }
22
31
23 protected DisposablePool() : this(Environment.ProcessorCount+1) {
32 protected DisposablePool() : this(Environment.ProcessorCount+1) {
24 }
33 }
25
34
26 public T Allocate() {
35 public T Allocate() {
27 if (m_disposed)
36 if (m_disposed)
28 throw new ObjectDisposedException(ToString());
37 throw new ObjectDisposedException(ToString());
29
38
30 T instance;
39 T instance;
31 if (m_queue.TryDequeue(out instance)) {
40 if (m_queue.TryDequeue(out instance)) {
32 Interlocked.Decrement(ref m_count);
41 Interlocked.Decrement(ref m_count);
33 } else {
42 } else {
34 instance = CreateInstance();
43 instance = CreateInstance();
35 Debug.Assert(!Object.Equals(instance, default(T)) || _isValueType);
44 Debug.Assert(!Object.Equals(instance, default(T)) || _isValueType);
36 }
45 }
37 return instance;
46 return instance;
38 }
47 }
39
48
40 protected abstract T CreateInstance();
49 protected abstract T CreateInstance();
41
50
42 protected virtual void CleanupInstance(T instance) {
51 protected virtual void CleanupInstance(T instance) {
43 }
52 }
44
53
45 public void Release(T instance) {
54 public void Release(T instance) {
46 if ( Object.Equals(instance,default(T)) && !_isValueType)
55 if ( Object.Equals(instance,default(T)) && !_isValueType)
47 return;
56 return;
48
57
49 Thread.MemoryBarrier();
58 Thread.MemoryBarrier();
50 if (m_count < m_size && !m_disposed) {
59 if (m_count < m_size && !m_disposed) {
51 Interlocked.Increment(ref m_count);
60 Interlocked.Increment(ref m_count);
52
61
53 CleanupInstance(instance);
62 CleanupInstance(instance);
54
63
55 m_queue.Enqueue(instance);
64 m_queue.Enqueue(instance);
56
65
57 // ΠΏΠΎΠΊΠ° элСмСнт возвращался Π² кСш, Π±Ρ‹Π»Π° Π½Π°Ρ‡Π°Ρ‚Π° опСрация освобоТдСния всСго кСша
66 // ΠΏΠΎΠΊΠ° элСмСнт возвращался Π² кСш, Π±Ρ‹Π»Π° Π½Π°Ρ‡Π°Ρ‚Π° опСрация освобоТдСния всСго кСша
58 // ΠΈ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΡƒΠΆΠ΅ Π·Π°ΠΊΠΎΠ½Ρ†Π΅Π½Π°, Π² Ρ‚Π°ΠΊΠΎΠΌ случаС слСдуСт ΠΈΠ·Π²Π»Π΅Ρ‡ΡŒ элСмСнт ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ ΠΈ
67 // ΠΈ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΡƒΠΆΠ΅ Π·Π°ΠΊΠΎΠ½Ρ†Π΅Π½Π°, Π² Ρ‚Π°ΠΊΠΎΠΌ случаС слСдуСт ΠΈΠ·Π²Π»Π΅Ρ‡ΡŒ элСмСнт ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ ΠΈ
59 // ΠΎΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΡ‚ΡŒ Π΅Π³ΠΎ. Если опСрация освобоТдСния кСша Π΅Ρ‰Π΅ Π½Π΅ Π·Π°Π²Ρ€Π΅ΡˆΠΈΠ»Π°ΡΡŒ, Ρ‚ΠΎ Π±ΡƒΠ΄Π΅Ρ‚
68 // ΠΎΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΡ‚ΡŒ Π΅Π³ΠΎ. Если опСрация освобоТдСния кСша Π΅Ρ‰Π΅ Π½Π΅ Π·Π°Π²Ρ€Π΅ΡˆΠΈΠ»Π°ΡΡŒ, Ρ‚ΠΎ Π±ΡƒΠ΄Π΅Ρ‚
60 // ΠΈΠ·ΡŠΡΡ‚ ΠΈ освобоТдСн ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½Ρ‹ΠΉ элСмСн, Ρ‡Ρ‚ΠΎ Π½Π΅ повлияСт Π½Π° Ρ…ΠΎΠ΄ всСго процСсса.
69 // ΠΈΠ·ΡŠΡΡ‚ ΠΈ освобоТдСн ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½Ρ‹ΠΉ элСмСн, Ρ‡Ρ‚ΠΎ Π½Π΅ повлияСт Π½Π° Ρ…ΠΎΠ΄ всСго процСсса.
61 if (m_disposed && m_queue.TryDequeue(out instance) && instance is IDisposable)
70 if (m_disposed && m_queue.TryDequeue(out instance) && instance is IDisposable)
62 ((IDisposable)instance).Dispose() ;
71 ((IDisposable)instance).Dispose() ;
63
72
64 } else {
73 } else {
65 if (instance is IDisposable)
74 var disposable = instance as IDisposable;
66 ((IDisposable)instance).Dispose();
75 if (disposable != null)
76 disposable.Dispose();
67 }
77 }
68 }
78 }
69
79
70 protected virtual void Dispose(bool disposing) {
80 protected virtual void Dispose(bool disposing) {
71 if (disposing) {
81 if (disposing) {
72 m_disposed = true;
82 m_disposed = true;
73 T instance;
83 T instance;
74 while (m_queue.TryDequeue(out instance))
84 while (m_queue.TryDequeue(out instance)) {
75 if (instance is IDisposable)
85 var disposable = instance as IDisposable;
76 ((IDisposable)instance).Dispose();
86 if (disposable != null)
87 disposable.Dispose();
88 }
77 }
89 }
78 }
90 }
79
91
80 #region IDisposable implementation
92 #region IDisposable implementation
81
93
82 public void Dispose() {
94 public void Dispose() {
83 Dispose(true);
95 Dispose(true);
84 GC.SuppressFinalize(this);
96 GC.SuppressFinalize(this);
85 }
97 }
86
98
87 #endregion
99 #endregion
88 }
100 }
89 }
101 }
90
102
General Comments 0
You need to be logged in to leave comments. Login now