缓存类的实现(C#)

缓存

小弟最近在编写一个O/RM组件(当然功能还是相当少的)。
大家都应该清楚把实体对象更新到数据库必须经过一系列的转换;特别是SQL语句的生成是比较费资源的,因为中间处里的东西实大是太多了。
在设计的过程中我就想如果一个对象插入数据库后把相应的Command保存在缓存中;下一次同一个类型的对象做这个操作时检测一下缓存如果有就直接拿来用这样效率应该会高些。
抱着这种想法就开始设计了(不过心里还是上上下下的,毕竟第一次尝试)。
因为缓存中的对象处理比较复杂点,在多线程中存在共享的问题,如果两个线程同时调用同一个Command这样一定会产生处理错误的!
为了更好地控制Command对象的共享,特别为Command定义了持久化的接口。
经过一段时间的设计和编写,算有点成果吧,顺把自己做的东西共享一下。

以下是组件测试的情况
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>
/// 数据缓存保存信息异步处理委托
/// </summary>
delegate  void EventSaveCache(object key,object value);
/// <summary>
/// 对象缓存类
/// </summary>
public class Cache
{
private MappingContainer mContainer;
/// <summary>
/// 获取或设置当前缓存对象所在的关系映象容器
/// </summary>
public MappingContainer Container
{
 get
 {
  return mContainer;
 }
 set
 {
  mContainer = value;
 }
}
/// <summary>
/// 构造缓存对象
/// </summary>
public Cache()
{
 //
 // TODO: 在此处添加构造函数逻辑
 //
}
/// <summary>
/// 用于缓存数据的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>
/// 把记录操作命令缓存到内存中
/// </summary>
/// <param name="key">标识</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;
  //如果缓存中已经存在这种命令的列表
  if(_Cache.ContainsKey(key))
  {
   _list = (System.Collections.IList)_Cache[key];
   
   if( count >0)//命令的缓存总数
   {
    if(_list.Count < count)//缓存数据量少于缓存总数
     _list.Add(value);
   }
   else
   {
    if(_list.Count < Container.Config.CommandBuffer)//缓存数小于组件的默认列表
     _list.Add(value);
   }
  }
  else//如果不存在列表
  {
   if(count >0 || Container.Config.CommandBuffer >0)//如果组件允许对象缓存
   {
    _list = new System.Collections.ArrayList();
    _list.Add(value);
    _Cache.Add(key,_list);
   }
  }
 }
}
/// <summary>
/// 从缓存中获取相关命令对象
/// </summary>
/// <param name="key">标识</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;
}

}

 

时间: 2024-09-15 16:10:31

缓存类的实现(C#)的相关文章

读写锁和缓存类实现

提高性能 读写锁:分为读锁和写锁,多个读锁不互斥,读锁与写锁互斥,写锁与写锁互斥,这是由JVM控制的,我们只需要上好相应的锁即可.如果代码只读数据,可以很多人同时读,但不能同时写,那就上读锁:如果代码修改数据,只能有一个人在写,且不能同时读取,那就上写锁.总之,读的时候上读锁,写的时候上写锁. import java.util.Random; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.

xml缓存类

特点: 读取机制:自动判断有无缓存了的xml文件,当xml文件存在数据,侧从xml获取数据,反之从数据库读取:缓存机制:根据xml文件生存时间和用户自定义的缓存时间判断缓存有无过期,过期侧生存新的xml文件: 有效减少数据库查询读取次数,缓存数据量小读取更快 修改了一下,加了两个方法,使用更方便 以下是引用片段:代码: <% Rem xml缓存类 '-------------------------------------------------------------------- '转载的时

一个比较蛋疼的php缓存类

php缓存类 $oFC = new FileCache(); $sKey = 'ab_123'; $data = $oFC -> get($sKey); if (is_null($data)) $oFC -> set($sKey, array('name' => 'ttt', 'datetime' => date('Y-m-d H:i:s')), 100000); print_r($data);   <?php final class FileCache { /** * *

asp.net的DataTable 缓存类。

asp.net|缓存 using System;using System.Web;using System.Data; namespace sc{ /// <summary> //**************************************/ // 说明:DateTable的缓存类. // 属性:name:缓存的名称.只写 // 属性:Values:缓存的值 读写 // 方法:CheckCache():检查是否有缓存.返回bool // 方法:MakeCacheEmpty():

ASP缓存类【先锋缓存类】Ver2004

<% '------------------------------------------------------------------------------------- '转发时请保留此声明信息,这段声明不并会影响你的速度! '************************** [先锋缓存类]Ver2004 ******************************** '作者:孙立宇.apollosun.ezhonghua '官方网站:http://www.lkstar.com

ThinkPHP文件缓存类代码分享

  ThinkPHP文件缓存类代码分享         取自ThinkPHP的文件缓存类代码,这里就不多废话了,小伙伴们自己看注释吧. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63

php文件缓存类用法实例分析

  这篇文章主要介绍了php文件缓存类用法,以实例形式较为详细的分析了php文件缓存类的定义.功能及具体使用技巧,非常具有实用价值,需要的朋友可以参考下 本文实例讲述了php文件缓存类用法.分享给大家供大家参考.具体如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 4

简单的php缓存类分享

 这篇文章主要介绍了一个php缓存类,文件名使用md5加密,大家参考使用吧 代码如下: <?php class Cache  {  private $dir = "data/cache/";//定义缓存目录   private $key='c_a_sss'; // 文件名md5加密密钥    function set_dir($dirpath)  {   $this->dir=$dirpath;   $this->make_dir($this->dir);  }

iOS网络编程之六——数据缓存类NSURLCache使用解析

iOS网络编程之六--数据缓存类NSURLCache使用解析 一.引言         在前面博客中,介绍了NSURLRequest请求类的相关使用方法,其中有介绍关于请求返回数据的缓存策略,实际上,iOS中具体缓存操作的管理是由NSURLCache类来实现的.NSURLRequest类介绍的博客地址如下: iOS中NSURLRequest相关使用:http://my.oschina.net/u/2340880/blog/620225. 二.NSURLCache中方法与属性 ? 1 2 3 4