以文本方式查看主题 - 中文XML论坛 - 专业的XML技术讨论区 (http://bbs.xml.org.cn/index.asp) -- 『 Dot NET,C#,ASP,VB 』 (http://bbs.xml.org.cn/list.asp?boardid=43) ---- 用C#建立通用对象池 (http://bbs.xml.org.cn/dispbbs.asp?boardid=43&rootid=&id=76600) |
-- 作者:卷积内核 -- 发布时间:9/5/2009 9:02:00 AM -- 用C#建立通用对象池 在系统设计中,经常会使用“池”的概念。比如数据库连接池,socket连接池,线程池,组件队列。“池”可以节省对象重复创建和初始化所耗费 的时间,可以简化对象获取和使用的过程。对于那些被系统频繁请求和使用的对象,如果使用这种机制,可以使系统性能得到很大提高。特别象数据库连接这种对 象,客户端与数据库服务器端建立连接时,是比较慢的,如果每次进行数据库操作,都要先进行数据库连接,系统效率将非常低下。 “池”的概念就是将被使用的对象事先创建好,保存在列表中,供客户端取用。当客户端取得一个对象时,这个对象就已经是按照特定上下文环境初始化好,马上即 可使用的了。当客户端使用完毕,需要将对象归还给“池”,最后,在系统生命期结束时,由“池”统一释放这些对象。从另一个概念上来说,这也是一种“以空间 换时间”的做法,我们在内存中保存一系列整装待命的对象,供人随时差遣。与系统效率相比,这些对象所占用的内存空间太微不足道了。 “池”的结构是通用的,就是不管他里面保存的是哪一种对象,他的工作方法都基本不变。无非是初始化一系列对象,然后提供一个获取可用对象,一个归还对象的接口。 基于这种考虑,我们可以建立一个通用的对象池,只要某些对象符合“一些基本要求”(这个基本要求,可以使用Interface模式来限定),就可以使用通用对象池来存取和管理。 创建一个接口,用于限定对象池中所保存的对象的基本行为: 复制C#代码保存代码public interface IDynamicObject { 我们在对象池中存放的对象,必须继承上面的接口,并实现接口定义的每一个方法。 Create方法中,用户可以用来创建实际的对象,如建立数据库连接,并打开这个连接;GetInnerObject方法,使用户可以返回这个实际 的对象,如一个SqlConnection对象;IsValidate方法是用来判断用户自定义对象的有效性的,是对象池决定是否重新创建对象的标志; Release方法中,用户可以进行资源释放工作。 有了上面的接口定义,为我们可以在列表中保存用户自定义对象打下了基础。下面就是要实现这个ObjectPool了。 用户自定义对象在我们的ObjectPool中,可以用列表存储,如ArrayList或者Hashtable,为了表示每个用户对象的状态,我们 还需要将用户自定义对象包装一下,然后在放到列表中保存。下面定义了一个ObjectPool类的子类,用于包装用户自定义对象: 复制C#代码保存代码private class PoolItem { public PoolItem(Type type, Object param) private void Create() public void Recreate() public void Release() public Object InnerObject public int InnerObjectHashcode public bool IsValidate public bool Using 这个类,一个关键的属性是Using,该属性表示对象是否正在被被用户使用。注意,PoolItem创建时,接受一个Object类型的Param参 数,这个参数最后被传递给用户自定义对象的Create方法。用户可以利用这一点,在创建ObjectPool时指定一些参数,供其自定义对象在创建时使 用。比如创建SocketPool时,将服务器IP,端口通过Param传递给自定义对象的Create方法,用户就可以在Create方法中连接指定的 服务器了。 以下是ObjectPool的具体实现代码: 复制C#代码保存代码public sealed class ObjectPool { public ObjectPool(Type type, Object create_param, Int32 init_size, Int32 capacity) _nCapacity = capacity; for (int i = 0; i < init_size; i++) _nCurrentSize = _listObjects.Count; public void Release() public Int32 CurrentSize public Int32 ActiveCount public Object GetOne() Int32 nFreeIndex = (Int32) _listFreeIndex[0]; if (!pitem.IsValidate) pitem.Using = true; public void FreeObject(Object obj) public Int32 DecreaseSize(Int32 size) for (int i = 0; i < nDecrease; i++) _listFreeIndex.Clear(); foreach (DictionaryEntry de in _listObjects)
|
-- 作者:卷积内核 -- 发布时间:9/5/2009 9:04:00 AM -- 虽然.NET对数据库连接已经提供了连接池,但是,经测试,使用上述通用对象池实现的数据库连接池,效率要比直接使用.NET管理的连接池高。因为他减少了Open和Close操作,从而节省了时间。 代码如下: 复制C#代码保存代码public class DBPool { public SqlConnectionObject() #region IDynamicObject Members public void Create(Object param) public Object GetInnerObject() public bool IsValidate() public void Release() #endregion private ObjectPool _Connections; public DBPool(string connection, int initcount, int capacity) public SqlConnection GetConnection() public void FreeConnection(SqlConnection sqlConn) public void Release() public int Count public int UsingCount public int DecreaseSize(int size) |
W 3 C h i n a ( since 2003 ) 旗 下 站 点 苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》 |
61.523ms |