项目常用算法之 一个C#资源池的实现
2009-03-23 08:20:42 来源:WEB开发网(以上测试只是简单的演示功能,详细的测试代码跟项目其他类有关,贴上反而复杂)
具体实现:
1 /// <summary>
2 /// 资源池,可以往里面加入资源,也可以取出来
3 /// </summary>
4 /// <typeparam name="T"></typeparam>
5 public class ResourcePool<T> : IDisposable where T : class, IDisposable
6 {
7 private static ResourcePool<T> pool;
8 IResourceProvider<T> resourceProvider;
9 static int maxResource;
10
11 public static int MaxResource
12 {
13 get { return ResourcePool<T>.maxResource; }
14
15 }
16 private ResourcePool(IResourceProvider<T> resourceProvider, int maxResource)
17 {
18 this.resourceProvider = resourceProvider;
19 ResourcePool<T>.maxResource = maxResource;
20 resources = new Dictionary<long,ResourceTag<T>> ();
21 }
22 public int ResourceCount
23 {
24 get
25 {
26 return resources.Keys.Count;
27 }
28 }
29
30 static object key3 = new object();
31 /// <summary>
32 /// 返回一个资源池,采用单件模式。
33 /// </summary>
34 /// <param name="resourceProvider"></param>
35 /// <returns></returns>
36 public static ResourcePool<T> Instance(IResourceProvider<T> resourceProvider, int maxResource)
37 {
38 if (pool == null)
39 {
40 lock (key3)
41 {
42 if (pool == null)
43 {
44 pool = new ResourcePool<T>(resourceProvider, maxResource);
45 }
46 }
47 }
48 return pool;
49 }
50 Dictionary<long,ResourceTag<T>> resources;
51 /// <summary>
52 ///从资源池中提取资源
53 /// </summary>
54 /// <param name="resourID">向资源用户输出的resourceID,返回资源时用它来返回特定资源</param>
55 /// <returns></returns>
56 public T GetResource(out long resourID)
57 {
58 T result = null;
59 result = getFreeResource(out resourID);
60 return result;
61 }
62 object key1 = new object();
63 private T getFreeResource(out long resourID)
64 {
65 lock (key1)
66 {
67 foreach (long key in resources.Keys)
68 {
69 if (!resources[key].InUse)
70 {
71 resources[key].InUse = true;
72 resourID = key;
73 return resources[key].Resource;
74 }
75 }
76 //申请新资源
77 T res = resourceProvider.Request();
78 if (res == null)//申请资源失败
79 {
80 resourID = getNullResourceID();
81 return null;
82 }
83 else
84 {
85 ResourceTag<T> tag = new ResourceTag<T>(res, true);
86 long id = newResourceID();
87 resources.Add(id, tag);
88 resourID=id;
89 return res;
90 }
91 }
92 }
93
94 private long getNullResourceID()
95 {
96 return -1;
97 }
98 /// <summary>
99 /// 产生新的资源号
100 /// </summary>
101 /// <returns></returns>
102 private long newResourceID()
103 {
104 return DateTime.Now.Ticks;
105 }
106
107
108 /// <summary>
109 /// 返回资源
110 /// </summary>
111 /// <param name="resource">ref类型的参数,将在函数内部设为null,意味着返回后不能再用。</param>
112 /// <param name="resourceID">获取资源时得到的那个resourceID。如果返回一个不正确的id,将抛出异常。</param>
113 public void ReturnResource(ref T resource, long resourceID)
114 {
115 if (!resources.ContainsKey(resourceID))
116 {
117 throw new InvalidOperationException("试图归还一个非法的资源。");
118 }
119 returnRes(ref resource,resourceID);
120 }
121 object key2 = new object();
122 private void returnRes(ref T resource, long resourceID)
123 {
124 T toDispose = null;
125 lock (key2)
126 {
127 ResourceTag<T> tag = resources[resourceID];
128 tag.InUse = false;
129 resources.Remove(resourceID);//当前的id将作废,不能再用
130 resource = null;//将当前的resource置空,不能再用
131 if (resources.Keys.Count >= maxResource)//达到上限,将释放资源
132 {
133 toDispose = resource;
134 }
135 else
136 {
137 resources.Add(newResourceID(), tag);
138 }
139 }
140 if (toDispose != null)
141 {
142 resourceProvider.Dispose(toDispose);
143 }
144 }
145 #region IDisposable 成员 及 析构方法
146
147 public void Dispose()
148 {
149 Dispose(true);
150 }
151 ~ResourcePool()
152 {
153 Dispose(false);
154 }
155 public virtual void Dispose(bool isDisposing)
156 {
157 foreach (long key in resources.Keys)
158 {
159 resources[key].Resource.Dispose();//释放资源
160 }
161 if (isDisposing)
162 {
163 key1 = null;
164 key2 = null;
165 key3 = null;
166 resourceProvider = null;
167 }
168 }
169 #endregion
170
171 }
172 internal class ResourceTag<T>
173 {
174 private T resource;
175
176 internal T Resource
177 {
178 get { return resource; }
179 set { resource = value; }
180 }
181 private bool inUse;
182
183 internal bool InUse
184 {
185 get { return inUse; }
186 set { inUse = value; }
187 }
188 public ResourceTag(T resource, bool inUse)
189 {
190 Resource = resource;
191 InUse = inUse;
192 }
193
194 }
195 /// <summary>
196 /// 这个接口用来产生ResourcePool管理的资源,比如数据库连接对象等
197 /// </summary>
198 /// <typeparam name="T"></typeparam>
199 public interface IResourceProvider<T> where T : class, IDisposable
200 {
201 /// <summary>
202 /// 获得资源
203 /// </summary>
204 /// <returns>成功则返回资源对象,否则返回null</returns>
205 T Request();
206 void Dispose(T resource);
207 }
更多精彩
赞助商链接