新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 本版讨论.NET,C#,ASP,VB技术
    [返回] 中文XML论坛 - 专业的XML技术讨论区计算机技术与应用『 Dot NET,C#,ASP,VB 』 → 万能对象池【C#实现】 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 6184 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: 万能对象池【C#实现】 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     卷积内核 帅哥哟,离线,有人找我吗?
      
      
      威望:8
      头衔:总统
      等级:博士二年级(版主)
      文章:3942
      积分:27590
      门派:XML.ORG.CN
      注册:2004/7/21

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给卷积内核发送一个短消息 把卷积内核加入好友 查看卷积内核的个人资料 搜索卷积内核在『 Dot NET,C#,ASP,VB 』的所有贴子 访问卷积内核的主页 引用回复这个贴子 回复这个贴子 查看卷积内核的博客楼主
    发贴心情 万能对象池【C#实现】

    如果一种类型的对象需要经常被创建、销毁,为了提高性能,我们通常需要使用“池”技术,就如线程池、TCP连接池等一样。那么需要使用池技术的对象一般有哪些特征了?

    (1)创建过程耗时

    (2)不需要保存客户状态

    (3)对象体积较大

    (4)频繁创建/销毁

    为了省事,我希望实现一个万能对象池组件,该对象池可以缓存任意类型的对象。下面给出对象池的接口:

    public interface IObjectPool
        {
            //objType为缓存的对象的类型,cArgs为缓存对象的构造参数
            bool   Initialize(Type objType ,object[] cArgs ,int minNum ,int maxNum) ;
            object RentObject() ;
            void   GiveBackObject(int objHashCode) ;
            void   Dispose() ;

            int MinObjCount {get ;}
            int MaxObjCount {get ;}
            int CurObjCount {get ;}
            int IdleObjCount {get ;}

            event CallBackObjPool PoolShrinked  ;
            event CallBackObjPool MemoryUseOut  ; //内存分配失败
        }

    public delegate void CallBackObjPool() ;
    上面接口中的各个方法的含义很清楚。其中PoolShrinked表示池中的对象个数有Max变为Min。

    我们可以考虑这样一种情况,当我们需要缓存的对象需要维持和一个客户之间的状态,那么也是可以的,如果是这样,所缓存的类型最好实现下面的IPooledObjSupporter接口。

    public interface IPooledObjSupporter : IDisposable
        {
            void Reset() ; //恢复对象为初始状态,当IObjectPool.GiveBackObject时调用
        }
    对象在实现该接口后,就可以被对象池在收到归还的对象时重置其状态了。整个对象池的实现代码如下:

    using System;
    using System.Collections ;
    using System.Reflection;

    namespace EnterpriseServerBase.Infrastructure
    {
        /**//// <summary>
        /// IObjectPool 的默认实现。
        /// 作者:朱伟 sky.zhuwei@163.com
        /// </summary>
        ObjectPool#region ObjectPool
        public class ObjectPool :IObjectPool
        {
            members#region members
            private Type destType = null ;
            private object[] ctorArgs = null ;
            private int minObjCount = 0 ;
            private int maxObjCount = 0 ;
            private int shrinkPoint = 0 ;
            private Hashtable hashTableObjs   = new Hashtable() ;
            private Hashtable hashTableStatus = new Hashtable() ; //key - isIdle        其中key就是hashcode
            private ArrayList keyList = new ArrayList() ;
            private bool supportReset = false ;
            #endregion

            IObjectPool 成员#region IObjectPool 成员
            public event CallBackObjPool PoolShrinked ;    
            public event CallBackObjPool MemoryUseOut ;

            public bool Initialize(Type objType, object[] cArgs, int minNum, int maxNum)
            {
                if(minNum < 1)
                {
                    minNum = 1 ;
                }
                if(maxNum < 5)
                {
                    maxNum = 5 ;
                }

                this.destType = objType ;
                this.ctorArgs = cArgs ;
                this.minObjCount = minNum ;
                this.maxObjCount = maxNum ;
                double cof = 1 - ((double)minNum /(double)maxNum) ;
                this.shrinkPoint = (int)(cof * minNum) ;

                //缓存的类型是否支持IPooledObjSupporter接口
                Type supType = typeof(IPooledObjSupporter) ;
                if(supType.IsAssignableFrom(objType))
                {
                    this.supportReset = true ;
                }

                this.InstanceObjects() ;

                return true ;
            }

            private void InstanceObjects()
            {
                for(int i=0 ;i<this.minObjCount ;i++)
                {
                    this.CreateOneObject() ;
                }
            }

            CreateOneObject ,DistroyOneObject#region CreateOneObject ,DistroyOneObject
            private int CreateOneObject()
            {
                object obj = null ;

                try
                {
                    obj = Activator.CreateInstance(this.destType ,this.ctorArgs) ;
                }
                catch(Exception ee) //分配内存失败!
                {
                    ee = ee ;
                    this.maxObjCount = this.CurObjCount ;
                    if(this.minObjCount > this.CurObjCount)
                    {
                        this.minObjCount = this.CurObjCount ;
                    }

                    if(this.MemoryUseOut != null)
                    {
                        this.MemoryUseOut() ;
                    }

                    return -1 ;
                }

                int key = obj.GetHashCode() ;
                this.hashTableObjs.Add(key ,obj) ;
                this.hashTableStatus.Add(key ,true ) ;
                this.keyList.Add(key) ;

                return key ;
            }

            private void DistroyOneObject(int key)
            {
                object target = this.hashTableObjs[key] ;
                IDisposable tar = target as IDisposable ;
                if(tar != null)
                {
                    tar.Dispose() ;
                }

                this.hashTableObjs.Remove(key) ;
                this.hashTableStatus.Remove(key) ;
                this.keyList.Remove(key) ;
            }
            #endregion

            public object RentObject()
            {
                lock(this)
                {
                    object target = null ;
                    foreach(int key in this.keyList)
                    {
                        if((bool)this.hashTableStatus[key]) //isIdle
                        {
                            this.hashTableStatus[key] = false ;
                            target = this.hashTableObjs[key] ;
                            break ;
                        }
                    }

                    if(target == null)
                    {
                        if(this.keyList.Count < this.maxObjCount)
                        {
                            int key = this.CreateOneObject() ;
                            if(key != -1)
                            {
                                this.hashTableStatus[key] = false ;
                                target = this.hashTableObjs[key] ;
                            }
                        }
                    }

                    return target ;
                }
                
            }

            GiveBackObject#region GiveBackObject
            public void GiveBackObject(int objHashCode)
            {
                if(this.hashTableStatus[objHashCode] == null)
                {
                    return ;
                }

                lock(this)
                {
                    this.hashTableStatus[objHashCode] = true ;
                    if(this.supportReset)
                    {
                        IPooledObjSupporter supporter = (IPooledObjSupporter)this.hashTableObjs[objHashCode] ;
                        supporter.Reset() ;
                    }

                    if(this.CanShrink())
                    {
                        this.Shrink() ;
                    }
                }
            }

            //能够收缩对象池
            private bool CanShrink()
            {
                int idleCount = this.GetIdleObjCount() ;    
                int busyCount = this.CurObjCount - idleCount ;

                return (busyCount < this.shrinkPoint) && (this.CurObjCount > (this.minObjCount + (this.maxObjCount - this.minObjCount)/2)) ;
            }
            
            private void Shrink()
            {
                while(this.CurObjCount > this.minObjCount)
                {
                    int destKey = -1 ;
                    foreach(int key in this.keyList)
                    {
                        if((bool)this.hashTableStatus[key])
                        {
                            destKey = key ;
                            break ;
                        }
                    }

                    if(destKey != -1)
                    {
                        this.DistroyOneObject(destKey) ;
                    }
                    else
                    {
                        break ;
                    }
                }

                if(this.PoolShrinked != null)
                {
                    this.PoolShrinked() ;
                }
            }
            #endregion

            public void Dispose()
            {
                Type supType = typeof(System.IDisposable) ;
                if(supType.IsAssignableFrom(this.destType))
                {
                    ArrayList list = (ArrayList)this.keyList.Clone() ;
                    foreach(int key in list)
                    {
                        this.DistroyOneObject(key) ;
                    }
                }

                this.hashTableStatus.Clear() ;
                this.hashTableObjs.Clear() ;
                this.keyList.Clear() ;
            }        

            property#region property
            public int MinObjCount
            {
                get
                {
                    return this.minObjCount ;
                }
            }

            public int MaxObjCount
            {
                get
                {
                    return this.maxObjCount ;
                }
            }

            public int CurObjCount
            {
                get
                {
                    return this.keyList.Count ;
                }
            }

            public int IdleObjCount
            {
                get
                {
                    lock(this)
                    {
                        return this.GetIdleObjCount() ;
                    }
                }
            }

            private int GetIdleObjCount()
            {
                int count = 0 ;
                foreach(int key in this.keyList)
                {
                    if((bool)this.hashTableStatus[key])
                    {
                        ++ count ;
                    }
                }

                return count ;
            }
            #endregion

            #endregion
        }
        #endregion
    }


       收藏   分享  
    顶(0)
      




    ----------------------------------------------
    事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2009/9/5 8:58:00
     
     卷积内核 帅哥哟,离线,有人找我吗?
      
      
      威望:8
      头衔:总统
      等级:博士二年级(版主)
      文章:3942
      积分:27590
      门派:XML.ORG.CN
      注册:2004/7/21

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给卷积内核发送一个短消息 把卷积内核加入好友 查看卷积内核的个人资料 搜索卷积内核在『 Dot NET,C#,ASP,VB 』的所有贴子 访问卷积内核的主页 引用回复这个贴子 回复这个贴子 查看卷积内核的博客2
    发贴心情 
    对象在实现该接口后,就可以被对象池在收到归还的对象时重置其状态了。整个对象池的实现代码如下:

    using System;
    using System.Collections ;
    using System.Reflection;

    namespace EnterpriseServerBase.Infrastructure
    {
        /**//// <summary>
        /// IObjectPool 的默认实现。
        /// 作者:朱伟 sky.zhuwei@163.com
        /// </summary>
        ObjectPool#region ObjectPool
        public class ObjectPool :IObjectPool
        {
            members#region members
            private Type destType = null ;
            private object[] ctorArgs = null ;
            private int minObjCount = 0 ;
            private int maxObjCount = 0 ;
            private int shrinkPoint = 0 ;
            private Hashtable hashTableObjs   = new Hashtable() ;
            private Hashtable hashTableStatus = new Hashtable() ; //key - isIdle        其中key就是hashcode
            private ArrayList keyList = new ArrayList() ;
            private bool supportReset = false ;
            #endregion

            IObjectPool 成员#region IObjectPool 成员
            public event CallBackObjPool PoolShrinked ;    
            public event CallBackObjPool MemoryUseOut ;

            public bool Initialize(Type objType, object[] cArgs, int minNum, int maxNum)
            {
                if(minNum < 1)
                {
                    minNum = 1 ;
                }
                if(maxNum < 5)
                {
                    maxNum = 5 ;
                }

                this.destType = objType ;
                this.ctorArgs = cArgs ;
                this.minObjCount = minNum ;
                this.maxObjCount = maxNum ;
                double cof = 1 - ((double)minNum /(double)maxNum) ;
                this.shrinkPoint = (int)(cof * minNum) ;

                //缓存的类型是否支持IPooledObjSupporter接口
                Type supType = typeof(IPooledObjSupporter) ;
                if(supType.IsAssignableFrom(objType))
                {
                    this.supportReset = true ;
                }

                this.InstanceObjects() ;

                return true ;
            }

            private void InstanceObjects()
            {
                for(int i=0 ;i<this.minObjCount ;i++)
                {
                    this.CreateOneObject() ;
                }
            }

            CreateOneObject ,DistroyOneObject#region CreateOneObject ,DistroyOneObject
            private int CreateOneObject()
            {
                object obj = null ;

                try
                {
                    obj = Activator.CreateInstance(this.destType ,this.ctorArgs) ;
                }
                catch(Exception ee) //分配内存失败!
                {
                    ee = ee ;
                    this.maxObjCount = this.CurObjCount ;
                    if(this.minObjCount > this.CurObjCount)
                    {
                        this.minObjCount = this.CurObjCount ;
                    }

                    if(this.MemoryUseOut != null)
                    {
                        this.MemoryUseOut() ;
                    }

                    return -1 ;
                }

                int key = obj.GetHashCode() ;
                this.hashTableObjs.Add(key ,obj) ;
                this.hashTableStatus.Add(key ,true ) ;
                this.keyList.Add(key) ;

                return key ;
            }

            private void DistroyOneObject(int key)
            {
                object target = this.hashTableObjs[key] ;
                IDisposable tar = target as IDisposable ;
                if(tar != null)
                {
                    tar.Dispose() ;
                }

                this.hashTableObjs.Remove(key) ;
                this.hashTableStatus.Remove(key) ;
                this.keyList.Remove(key) ;
            }
            #endregion

            public object RentObject()
            {
                lock(this)
                {
                    object target = null ;
                    foreach(int key in this.keyList)
                    {
                        if((bool)this.hashTableStatus[key]) //isIdle
                        {
                            this.hashTableStatus[key] = false ;
                            target = this.hashTableObjs[key] ;
                            break ;
                        }
                    }

                    if(target == null)
                    {
                        if(this.keyList.Count < this.maxObjCount)
                        {
                            int key = this.CreateOneObject() ;
                            if(key != -1)
                            {
                                this.hashTableStatus[key] = false ;
                                target = this.hashTableObjs[key] ;
                            }
                        }
                    }

                    return target ;
                }
                
            }

            GiveBackObject#region GiveBackObject
            public void GiveBackObject(int objHashCode)
            {
                if(this.hashTableStatus[objHashCode] == null)
                {
                    return ;
                }

                lock(this)
                {
                    this.hashTableStatus[objHashCode] = true ;
                    if(this.supportReset)
                    {
                        IPooledObjSupporter supporter = (IPooledObjSupporter)this.hashTableObjs[objHashCode] ;
                        supporter.Reset() ;
                    }

                    if(this.CanShrink())
                    {
                        this.Shrink() ;
                    }
                }
            }

            //能够收缩对象池
            private bool CanShrink()
            {
                int idleCount = this.GetIdleObjCount() ;    
                int busyCount = this.CurObjCount - idleCount ;

                return (busyCount < this.shrinkPoint) && (this.CurObjCount > (this.minObjCount + (this.maxObjCount - this.minObjCount)/2)) ;
            }
            
            private void Shrink()
            {
                while(this.CurObjCount > this.minObjCount)
                {
                    int destKey = -1 ;
                    foreach(int key in this.keyList)
                    {
                        if((bool)this.hashTableStatus[key])
                        {
                            destKey = key ;
                            break ;
                        }
                    }

                    if(destKey != -1)
                    {
                        this.DistroyOneObject(destKey) ;
                    }
                    else
                    {
                        break ;
                    }
                }

                if(this.PoolShrinked != null)
                {
                    this.PoolShrinked() ;
                }
            }
            #endregion

            public void Dispose()
            {
                Type supType = typeof(System.IDisposable) ;
                if(supType.IsAssignableFrom(this.destType))
                {
                    ArrayList list = (ArrayList)this.keyList.Clone() ;
                    foreach(int key in list)
                    {
                        this.DistroyOneObject(key) ;
                    }
                }

                this.hashTableStatus.Clear() ;
                this.hashTableObjs.Clear() ;
                this.keyList.Clear() ;
            }        

            property#region property
            public int MinObjCount
            {
                get
                {
                    return this.minObjCount ;
                }
            }

            public int MaxObjCount
            {
                get
                {
                    return this.maxObjCount ;
                }
            }

            public int CurObjCount
            {
                get
                {
                    return this.keyList.Count ;
                }
            }

            public int IdleObjCount
            {
                get
                {
                    lock(this)
                    {
                        return this.GetIdleObjCount() ;
                    }
                }
            }

            private int GetIdleObjCount()
            {
                int count = 0 ;
                foreach(int key in this.keyList)
                {
                    if((bool)this.hashTableStatus[key])
                    {
                        ++ count ;
                    }
                }

                return count ;
            }
            #endregion

            #endregion
        }
        #endregion
    }

    ----------------------------------------------
    事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2009/9/5 8:58:00
     
     GoogleAdSense
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 Dot NET,C#,ASP,VB 』的所有贴子 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/12/27 1:57:06

    本主题贴数2,分页: [1]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    375.000ms