.net快速开发平台

工作流+智能表单
帮助企业快速应对变化

统计

使用.net技术创建一个小型对象池

本文中使用的关键词
1、ObjPool ,对象池类,用于存放对象。
2、CustomerObj,客户对象,就是我们放在对象池中对象。
3、OrigianlObjWrapper ,对象包装类,用于包装放在ObjPool 中的客户对象。
4、对象池空闲对象列表,用于记录放在对象池中的并未被客户使用的CustomerObj对象列表。
5、对象池正在使用的对象列表,用于记录放在对象池中的正在被客户使用的CustomerObj对象列表。

本文的示例代码将解决以下问题:
1、创建一个对象池,用以存放创建较为困难的对象。
      创建一个对象池类ObjPool,用作存放对象的容器。ObjPool类有两个主要的成员空闲对象列表和正在使用的对象列表,这两个列表用Hashtable来实现。
2、对象实现管理自己的TimeOut。
       放在对象池空闲对象列表中的CustomerObj对象要在某个特定的时间段内没有被使用,将会被对象池ObjPool 销毁。为了能纪录放在对象池中的CustomerObj对象的使用纪录,我们需要对CustomerObj对象进行一个包装(因为我们再写这个对象池类的时候还不知道我们将要面对什么样的CustomerObj对象),我们是用一个包装类OrigianlObjWrapper ,这个类中有几个主要成员,一个用于开始使用时间的字段,一个标示对象本身的字符串(用于在对象池的空闲对象列表和正在使用的对象列表中唯一标示自己,这里使用 System.Guid 类),还有一个重要的成员就是对CustomerObj的引用。这样一下,我们放在对象池中的实际对象就是这个CustomerObj对象的包装对象OrigianlObjWrapper ,我们每次在对象池中操作的是OrigianlObjWrapper 对象,然后再通过OrigianlObjWrapper 中的CustomerObj引用来取得CustomerObj对象。
好了,下面就是这个对象池的具体实现


using System.Collections;
using System.Threading;  
using System;
using System.Runtime.Remoting.Messaging;
namespace Com.Util
{
 class TimerState
 {
  public int counter = 0;
  public Timer tmr;
 
 }

 /// <summary>
 /// 对象包装类,用于包装初始化时对象池中的类
 /// </summary>
 public class OrigianlObjWrapper
 {

  // 一个标示自己的字符串
  public string mID;  

  // 记录上次使用的时间,用于检查将长时间不用的对象清理掉
  public System.DateTime  mLastUsedTime;


  public object originalObj;
  

  public OrigianlObjWrapper():base()
  {
   this.mID = System.Guid.NewGuid().ToString();
   this.mLastUsedTime = System.DateTime.Now; 
  }
 }
 
 /// <summary>
 /// 对象池的使用注意:
 /// 1、使用前调用InitObjPool()方法,以初始化对象池
 /// 2、使用GetFreeObj()方法得到一个可用的对象(从对象池中)
 /// 3、在对象是用完后调用静态方法FreeObj()以释放对象(放回到对象池中)
 /// </summary>
 public class ObjPool:System.IDisposable
 {

  
  /// <summary>
  /// 检查对象定时器执行的时间间隔.单位为豪秒
  /// </summary>
  private   int mTimeSpanOfTimer=7200000;//两小时;

  /// <summary>
  /// 对象池中对象的类型
  /// </summary>
  private   System.Type mType ;

  /// <summary>
  /// 如果一个对象在这个时间短内一直没有释放,则认为是一个错误,强行进行对象释放.如果对象执行的方法需要
  /// 的时间比较长,则应该增大这个时间.单位为分钟
  /// </summary>
  private   int mUsedTimeOut = 3;

  /// <summary>
  /// 如果检查对象在mFreeTimeOut时间段内没有使用,则将其删除.单位为分钟
  /// </summary>
  private   int mFreeTimeOut = 60;
 
  /// <summary>
  /// 空闲对象列表
  /// </summary>
  private   System.Collections.Hashtable freeObjList = new System.Collections.Hashtable();
  /// <summary>
  /// 正在使用的对象列表
  /// </summary>
  private   System.Collections.Hashtable usedObjList = new System.Collections.Hashtable();

   /// <summary>
  /// 定时器,用于定时清除一些长时间不用的对象和一些使用时间过长的对象(根据SysConfig.CheckObj_TimeOut的值定时执行)
  /// </summary>
  private   System.Threading.Timer mTimer;

  
  /// <summary>
  /// 初始化对象池
  /// </summary>
  /// <param name="timeSpanOfTimer">检查对象状态的定时器时间间隔</param>
  /// <param name="Obj_UsedTimeOut">如果对象在这段时间中一直处于使用状态,则认为对象没有正常释放,则从对象池中删除</param>
  /// <param name="Obj_FreeTimeOut">如果对象在这段时间内没有使用,则从对象池中删除</param>
  /// <param name="type"></param>
  public   void InitObjPool(int timeSpanOfTimer,int obj_UsedTimeOut,int obj_FreeTimeOut,System.Type type)
  {
   mFreeTimeOut =obj_FreeTimeOut;
   mUsedTimeOut = obj_UsedTimeOut;
   mTimeSpanOfTimer =timeSpanOfTimer;
   mType = type;
   BeginTimerOfClearObj();
  }
  
 
  /// <summary>
  /// 从对象池中中获取一个可用的对象
  /// </summary>
  /// <returns></returns>
  public   object GetFreeObj()
  {
   
   OrigianlObjWrapper co = null; 
   object originalObj = null;
   lock(this)
   {
    Hashtable hf = this.freeObjList ;
    Hashtable hu = this.usedObjList ;
    IDictionaryEnumerator enumerator    = hf.GetEnumerator();
    if(enumerator.MoveNext())
    {  
     co = (OrigianlObjWrapper)enumerator.Value;
     hf.Remove(co.mID);
     hu.Add(co.mID,co);
     originalObj  = co.originalObj;
    }
    else
    {
     co = new OrigianlObjWrapper();
     originalObj =  mType.Assembly.CreateInstance(mType.FullName);
     co.originalObj = originalObj;
     hu.Add(co.mID,co);
    }
   } 
   return originalObj;
  }
  private  OrigianlObjWrapper GetWraper(object obj)
  {
   OrigianlObjWrapper co = null;
   OrigianlObjWrapper ro = null;
   Hashtable h = null;
   IDictionaryEnumerator enumerator = null; 
   lock(this)
   {
    h = usedObjList;
    enumerator  = h.GetEnumerator();
    while(enumerator.MoveNext())
    {
     co = (OrigianlObjWrapper)enumerator.Value ;
     if(co.originalObj.Equals(obj))
     {
      ro = co;
     }
    }
   }

   return ro;
  }
  /// <summary>
  /// 将用过的对象放回到对象池中
  /// </summary>
  /// <param name="checkObj"></param>
  /// <returns></returns>
  [OneWay]
  public  bool FreeObj(object obj)
  { 
   //Thread.Sleep(6000);
   OrigianlObjWrapper o = GetWraper(obj);
   if (o == null)
    return false;
   o.mLastUsedTime = System.DateTime.Now;
   lock(this)
   {
    usedObjList.Remove(o.mID );
    freeObjList.Add(o.mID,o);
   }
   return true;

  }
 
  
  /// <summary>
  /// 开始定时清除一些长时间不用的对象
  /// </summary>
  private void BeginTimerOfClearObj()
  {
   if(mTimer  == null)
   {
    TimerState s = new TimerState();
    TimerCallback timerDelegate = new TimerCallback(CheckStatus); 
    mTimer = new System.Threading.Timer(timerDelegate,s,mTimeSpanOfTimer ,mTimeSpanOfTimer); 
    s.tmr = mTimer;
   }
   
  } 
  /// <summary>
  /// 检查对象本身状态(正在使用,还是空闲。如果空闲的时间大于某个值,则将对象删除)
  /// </summary>
  /// <param name="state"></param>
  private  void CheckStatus(object state)
  {
  
   OrigianlObjWrapper co = null;
   System.DateTime dt = System.DateTime.Now;
   Hashtable h = null;
   IDictionaryEnumerator enumerator = null;
   ArrayList  a= new ArrayList();
   //
   //清除长时间不用的对象
   //
   lock(this)
   {
    h = freeObjList;
    enumerator  = h.GetEnumerator();
    a.Clear();
    while(enumerator.MoveNext())
    {
     co = (OrigianlObjWrapper)enumerator.Value ;
     if(co.mLastUsedTime.AddMinutes(mFreeTimeOut)<dt)
     {
      a.Add(enumerator.Key); 
     }
    }
    for(int i=0 ;i<a.Count;i++)
    {
     h.Remove( (string)a[i]);
    }
   }

   //
   //清除一些因为发生错误而没有把自己放在空闲列表中的对象,这些对象没有在使用,但却在使用对象列表中
   //
   lock(this)
   {
    h = usedObjList;
    enumerator  = h.GetEnumerator();
    a.Clear();
    while(enumerator.MoveNext())
    {
     co = (OrigianlObjWrapper)enumerator.Value ;
     if(co.mLastUsedTime.AddMinutes(mUsedTimeOut)<dt)
     {
      a.Add(enumerator.Key); 
     }
    }
    for(int i=0 ;i<a.Count;i++)
    {
     h.Remove( (string)a[i]);
    }
   }
   
  } 
  public void Dispose()
  {
   Dispose(true);
   GC.SuppressFinalize(this);
  }

  ~  ObjPool()
  {
   Dispose(true); 
  }
  public virtual void Dispose(bool disposing)
  {
   if (! disposing)
    return; // we're being collected, so let the GC take care of this object
   if(mTimer != null)
   {
    mTimer.Dispose();
    mTimer = null;

   }
   if(usedObjList != null)
   {
    usedObjList = null;
    
    
   }
   if(freeObjList != null)
   {
    freeObjList = null;
   }
   
  }
  public  int GetUsedObjCount()
  {
   int count =-1 ;
   if(usedObjList != null)
   {
    count = usedObjList.Count;
   }
   return count;
  }
  public  int GetFreeObjCount()
  {
   int count =-1 ;
   if(freeObjList != null)
   {
    count = freeObjList.Count;
   }
   return count;
  }

 }// END CLASS DEFINITION ObjPool

}

posted on 2004-03-04 09:47  chegan  阅读(1792)  评论(3编辑  收藏