明輝手游網(wǎng)中心:是一個免費提供流行視頻軟件教程、在線學(xué)習(xí)分享的學(xué)習(xí)平臺!

緩存類的完成(C#)

[摘要]小弟最近在編寫一個O/RM組件(當(dāng)然功能還是相當(dāng)少的)。大家都應(yīng)該清楚把實體對象更新到數(shù)據(jù)庫必須經(jīng)過一系列的轉(zhuǎn)換;特別是SQL語句的生成是比較費資源的,因為中間處里的東西實大是太多了。在設(shè)計的過程中我就想如果一個對象插入數(shù)據(jù)庫后把相應(yīng)的Command保存在緩存中;下一次同一個類型的對象做這個操作時...

小弟最近在編寫一個O/RM組件(當(dāng)然功能還是相當(dāng)少的)。
大家都應(yīng)該清楚把實體對象更新到數(shù)據(jù)庫必須經(jīng)過一系列的轉(zhuǎn)換;特別是SQL語句的生成是比較費資源的,因為中間處里的東西實大是太多了。
在設(shè)計的過程中我就想如果一個對象插入數(shù)據(jù)庫后把相應(yīng)的Command保存在緩存中;下一次同一個類型的對象做這個操作時檢測一下緩存如果有就直接拿來用這樣效率應(yīng)該會高些。
抱著這種想法就開始設(shè)計了(不過心里還是上上下下的,畢竟第一次嘗試)。
因為緩存中的對象處理比較復(fù)雜點,在多線程中存在共享的問題,如果兩個線程同時調(diào)用同一個Command這樣一定會產(chǎn)生處理錯誤的!
為了更好地控制Command對象的共享,特別為Command定義了持久化的接口。
經(jīng)過一段時間的設(shè)計和編寫,算有點成果吧,順把自己做的東西共享一下。


以下是組件測試的情況
P4 2.4 1G
SqlServer sp3

運行的代碼大概如下:
Entitys.Customers customer = new Test.Entitys.Customers();
DateTime dt = DateTime.Now;
using(HFSoft.Data.IDataSession session = mapcontainer.OpenSession())
{
 session.Open();
 for(int i =0;i<2000;i++)
 {
  customer.CustomerID = Guid.NewGuid().ToString();
  customer.CompanyName = "henry";
  session.Save(customer);
 }
}
tp1 = new TimeSpan(DateTime.Now.Ticks - dt.Ticks);


不開啟緩存(5個線程運行時間)
00:00:05.7031250
00:00:06.8281250
00:00:05.0156250
00:00:06.6875000
00:00:06.4218750
--------------------------------------------------------
開啟5個命令緩存(5個線程運行時間)
00:00:04.8906250
00:00:03.5625000
00:00:02.8750000
00:00:04.9375000
00:00:05.4843750
---------------------------------------------------------

以下是緩存類的源碼
/// <summary>
/// 數(shù)據(jù)緩存保存信息異步處理委托
/// </summary>
delegate  void EventSaveCache(object key,object value);
/// <summary>
/// 對象緩存類
/// </summary>
public class Cache
{
private MappingContainer mContainer;
/// <summary>
/// 獲取或設(shè)置當(dāng)前緩存對象所在的關(guān)系映象容器
/// </summary>
public MappingContainer Container
{
 get
 {
  return mContainer;
 }
 set
 {
  mContainer = value;
 }
}
/// <summary>
/// 構(gòu)造緩存對象
/// </summary>
public Cache()
{
 //
 // TODO: 在此處添加構(gòu)造函數(shù)邏輯
 //
}
/// <summary>
/// 用于緩存數(shù)據(jù)的Hashtable
/// </summary>
protected  System.Collections.Hashtable _Cache = new System.Collections.Hashtable();
protected Object _LockObj = new object();
/// <summary>
/// 獲取指定鍵值的對象
/// </summary>
/// <param name="key">鍵值</param>
/// <returns>object</returns>
public virtual object GetObject(object key)
{
 if(_Cache.ContainsKey(key))
  return _Cache[key];
 return null;
}
/// <summary>
/// 把對象按指定的鍵值保存到緩存中
/// </summary>
/// <param name="key">鍵值</param>
/// <param name="value">保存的對象</param>
public void SaveCaech(object key,object value)
{
 EventSaveCache save = new EventSaveCache(SetCache);
 IAsyncResult ar = save.BeginInvoke(key,value,new System.AsyncCallback(Results),null);
}
private  void Results(IAsyncResult ar)
{
 EventSaveCache fd = (EventSaveCache)((AsyncResult)ar).AsyncDelegate;
 fd.EndInvoke(ar);
}
/// <summary>
/// 把對象按指定的鍵值保存到緩存中
/// </summary>
/// <param name="key">鍵值</param>
/// <param name="value">保存的對象</param>
protected virtual void SetCache(object key ,object value)
{
 lock(_LockObj)
 {
  if(!_Cache.ContainsKey(key))
   _Cache.Add(key,value);
 }
}
public int Count
{
 get
 {
  return _Cache.Count;
 }
}
/// <summary>
/// 在緩存中刪除指定鍵值的對象
/// </summary>
/// <param name="key">鍵值</param>
public virtual void DelObject(object key)
{
 lock(_Cache.SyncRoot)
 {
  _Cache.Remove(key);
 }
}
/// <summary>
/// 清除緩存中所有對象
/// </summary>
public virtual void Clear()
{
 lock(_Cache.SyncRoot)
 {
  _Cache.Clear();
 }
}
}

/// <summary>
///針對一條記錄操作命令的緩存類
/// </summary>
public class CachePersistentCommand:Cache
{
 
/// <summary>
/// 把記錄操作命令緩存到內(nèi)存中
/// </summary>
/// <param name="key">標(biāo)識</param>
/// <param name="value">值</param>
protected override void SetCache(object key, object value)
{
 lock(_LockObj)
 {
  int count=0;
  if(Container.Config.CommandsCache.ContainsKey(key))
   count=(int) Container.Config.CommandsCache[key];
  System.Collections.IList _list;
  //如果緩存中已經(jīng)存在這種命令的列表
  if(_Cache.ContainsKey(key))
  {
   _list = (System.Collections.IList)_Cache[key];
    
   if( count >0)//命令的緩存總數(shù)
   {
    if(_list.Count < count)//緩存數(shù)據(jù)量少于緩存總數(shù)
     _list.Add(value);
   }
   else
   {
    if(_list.Count < Container.Config.CommandBuffer)//緩存數(shù)小于組件的默認(rèn)列表
     _list.Add(value);
   }
  }
  else//如果不存在列表
  {
   if(count >0 Container.Config.CommandBuffer >0)//如果組件允許對象緩存
   {
    _list = new System.Collections.ArrayList();
    _list.Add(value);
    _Cache.Add(key,_list);
   }
  }
 }
}
/// <summary>
/// 從緩存中獲取相關(guān)命令對象
/// </summary>
/// <param name="key">標(biāo)識</param>
/// <returns>IPersistentCommand</returns>
public override object GetObject(object key)
{
  
 if(_Cache.Contains(key))//如果命令存在緩沖中
 {
  foreach(IPersistentCommand cmd in (System.Collections.IList)_Cache[key])
  {
   if(!cmd.State)//命令是否可以過行鎖定
    if(cmd.Lock())//命令鎖定
     return cmd;
  }
 }
 return null;
}


}





標(biāo)簽:緩存類的完成(C#)