程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> 關於C# >> 項目常用算法之一個C#資源池的實現

項目常用算法之一個C#資源池的實現

編輯:關於C#

這個資源池用來管理程序的寶貴資源。

主要的類是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 /// <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     }

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved