WEB开发网
开发学院软件开发C语言 项目常用算法之 一个C#资源池的实现 阅读

项目常用算法之 一个C#资源池的实现

 2009-03-23 08:20:42 来源:WEB开发网   
核心提示: (以上测试只是简单的演示功能,详细的测试代码跟项目其他类有关,项目常用算法之 一个C#资源池的实现(2),贴上反而复杂)具体实现: 1 /// <summary> 2 /// 资源池,可以往里面加入资源,不能再用131 if (resources.Keys.Count >

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

具体实现:

  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 

Tags:项目 常用 算法

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接