龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > web编程 > asp.net编程 >

C#实现管理程序资源池源码

时间:2009-12-21 11:47来源:未知 作者:admin 点击:
分享到:
实现的这个资源池用来管理程序的宝贵资源。 主要的类是ResourcePoolT。 用户可以通过调用GetResource方法请求一个资源,用完之后通过ReturnResource归还给资源池。由资源池决定什么时候释放
实现的这个资源池用来管理程序的宝贵资源。
主要的类是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 }

(以上测试只是简单的演示功能,详细的测试代码跟项目其他类有关,贴上反而复杂)

具体实现:

  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    }
精彩图集

赞助商链接