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