##// END OF EJS Templates
docs
cin -
r153:b933ec88446e v2
parent child
Show More
@@ -1,20 +1,25
1 1 using System;
2 2 using System.Collections.Generic;
3 3
4 4 namespace Implab.Components {
5 5 /// <summary>
6 6 /// Global application components and services.
7 7 /// </summary>
8 8 public static class App {
9 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 16 public static ICollection<object> RootContainer {
12 17 get { return _root; }
13 18 }
14 19
15 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 1 using System;
2 2 using System.Collections.Generic;
3 3 using System.Linq;
4 4
5 5 namespace Implab.Components {
6 6 /// <summary>
7 /// Component container.
7 /// Component container, used to store track components in multi-threaded environmment.
8 8 /// </summary>
9 9 /// <remarks>Instanses of this class are thread safe.</remarks>
10 10 public class ComponentContainer<T> : Disposable, ICollection<T> {
11 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 19 public void Clear() {
14 20 T[] removed;
15 21
16 22 lock (m_components) {
17 23 removed = new T[m_components.Count];
18 24 m_components.CopyTo(removed);
19 25 m_components.Clear();
20 26 }
21 27
22 28 foreach (var item in removed.OfType<IDisposable>())
23 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 36 public bool Contains(T item) {
27 37 lock (m_components)
28 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 46 public void CopyTo(T[] array, int arrayIndex) {
32 47 lock (m_components)
33 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 55 public bool Remove(T item) {
37 56 lock (m_components)
38 57 return m_components.Remove(item);
39 58 }
40 59
60 /// <summary>
61 /// Gets the count of components in the collection.
62 /// </summary>
41 63 public int Count {
42 64 get {
43 65 lock (m_components)
44 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 76 public bool IsReadOnly {
49 77 get {
50 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 86 public IEnumerator<T> GetEnumerator() {
55 87 T[] items;
56 88 lock (m_components) {
57 89 items = new T[m_components.Count];
58 90 m_components.CopyTo(items);
59 91 return (IEnumerator<T>)items.GetEnumerator();
60 92 }
61 93 }
62 94
63 95 System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
64 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 106 public void Add(T item) {
68 107 Safe.ArgumentNotNull(item, "item");
69 108
70 109 lock (m_components) {
71 110 if (IsDisposed)
72 111 Safe.Dispose(item);
73 112 else
74 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 121 protected override void Dispose(bool disposing) {
79 122 base.Dispose(disposing);
80 123 Clear();
81 124 }
82 125 }
83 126 }
84 127
@@ -1,90 +1,102
1 1 using System;
2 2 using Implab.Parallels;
3 3 using System.Threading;
4 4 using System.Diagnostics;
5 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 17 public abstract class DisposablePool<T> : IDisposable {
9 18 readonly int m_size;
10 19 readonly AsyncQueue<T> m_queue = new AsyncQueue<T>();
11 20
12 21 [SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes")]
13 22 static readonly bool _isValueType = typeof(T).IsValueType;
14 23
15 24 bool m_disposed;
16 25
17 26 int m_count;
18 27
19 28 protected DisposablePool(int size) {
20 29 m_size = size;
21 30 }
22 31
23 32 protected DisposablePool() : this(Environment.ProcessorCount+1) {
24 33 }
25 34
26 35 public T Allocate() {
27 36 if (m_disposed)
28 37 throw new ObjectDisposedException(ToString());
29 38
30 39 T instance;
31 40 if (m_queue.TryDequeue(out instance)) {
32 41 Interlocked.Decrement(ref m_count);
33 42 } else {
34 43 instance = CreateInstance();
35 44 Debug.Assert(!Object.Equals(instance, default(T)) || _isValueType);
36 45 }
37 46 return instance;
38 47 }
39 48
40 49 protected abstract T CreateInstance();
41 50
42 51 protected virtual void CleanupInstance(T instance) {
43 52 }
44 53
45 54 public void Release(T instance) {
46 55 if ( Object.Equals(instance,default(T)) && !_isValueType)
47 56 return;
48 57
49 58 Thread.MemoryBarrier();
50 59 if (m_count < m_size && !m_disposed) {
51 60 Interlocked.Increment(ref m_count);
52 61
53 62 CleanupInstance(instance);
54 63
55 64 m_queue.Enqueue(instance);
56 65
57 66 // пока элемент возвращался в кеш, была начата операция освобождения всего кеша
58 67 // и возможно уже законцена, в таком случае следует извлечь элемент обратно и
59 68 // освободить его. Если операция освобождения кеша еще не заврешилась, то будет
60 69 // изъят и освобожден произвольный элемен, что не повлияет на ход всего процесса.
61 70 if (m_disposed && m_queue.TryDequeue(out instance) && instance is IDisposable)
62 71 ((IDisposable)instance).Dispose() ;
63 72
64 73 } else {
65 if (instance is IDisposable)
66 ((IDisposable)instance).Dispose();
74 var disposable = instance as IDisposable;
75 if (disposable != null)
76 disposable.Dispose();
67 77 }
68 78 }
69 79
70 80 protected virtual void Dispose(bool disposing) {
71 81 if (disposing) {
72 82 m_disposed = true;
73 83 T instance;
74 while (m_queue.TryDequeue(out instance))
75 if (instance is IDisposable)
76 ((IDisposable)instance).Dispose();
84 while (m_queue.TryDequeue(out instance)) {
85 var disposable = instance as IDisposable;
86 if (disposable != null)
87 disposable.Dispose();
88 }
77 89 }
78 90 }
79 91
80 92 #region IDisposable implementation
81 93
82 94 public void Dispose() {
83 95 Dispose(true);
84 96 GC.SuppressFinalize(this);
85 97 }
86 98
87 99 #endregion
88 100 }
89 101 }
90 102
General Comments 0
You need to be logged in to leave comments. Login now