好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

自己封装的内存缓存类DotNet.Caches.Bytecached

自己封装的内存缓存类DotNet.Caches.Bytecached

自己封装的内存缓存类DotNet.Caches.Bytecached

Bytecached 类是 DSS.NET (Distributed State Service分布式状态服务)、 DFS.NET (Distributed File System分布式文件系统)中的一个核心内存缓存类。

在DSS.NET中用于保存和管理网站用户的Session数据。

在DFS.NET中用于缓存使用频率较高的文件数据。

特性:

1、使用读写锁实现多线程并发控制

2、多种过期数据清理方式

3、精准的容量控制

4、以最小的系统开销进行数据清理

在一个对性能要求比较高的系统中,都需要用缓存来保存一临时数据。也许你正在寻找。。。

View Code

 1   using   System;
    2   using   System.Collections.Generic;
    3   using   System.Collections.ObjectModel;
    4   using   System.ComponentModel;
    5   using   System.Diagnostics;
    6   using   System.Linq;
    7   using   System.Threading;
    8   using   DotNet.Utilities;
    9  
  10   namespace   DotNet.Caches
   11   {
   12       public   class   Bytecached : IDisposable
   13       {
   14           private   readonly  IDictionary< string ,  byte []>  _caches;
   15           private   readonly  IDictionary< string , DateTime>  _times;
   16           private   long   _size;
   17           private   readonly   ReaderWriterLock _readerWriterLock;
   18           private   readonly   BackgroundWorker _checkWorker;
   19  
  20           ///   <summary> 
  21           ///   最大容量/B
   22           ///   </summary> 
  23           public   long  MaxSize {  get ;  set  ; }
   24  
  25           ///   <summary> 
  26           ///   是否启用缓存
   27           ///   </summary> 
  28           public   bool  Enabled {  get ;  set  ; }
   29  
  30           ///   <summary> 
  31           ///   超时时间
   32           ///   </summary> 
  33           public  TimeSpan Timeout {  get ;  set  ; }
   34  
  35           ///   <summary> 
  36           ///   一次清理数量
   37           ///   </summary> 
  38           public   int  ClearCount {  get ;  set  ; }
   39  
  40           ///   <summary> 
  41           ///   是否正在检查并清理超时缓存
   42           ///   </summary> 
  43           public   bool  Checking {  get ;  private   set  ; }
   44  
  45           ///   <summary> 
  46           ///   构造
   47           ///   </summary> 
  48           ///   <param name="timingcheck">  定时检查时间  </param> 
  49           public  Bytecached(TimeSpan timingcheck =  default  (TimeSpan))
   50           {
   51              _caches =  new  Dictionary< string ,  byte []> ();
   52              _times =  new  Dictionary< string , DateTime> ();
   53              _readerWriterLock =  new   ReaderWriterLock();
   54              MaxSize =  64 * 1024 * 1024  ;
   55              Enabled =  true  ;
   56              ClearCount =  1  ;
   57  
  58               #region  检查并清理缓存
  59  
  60               if  (timingcheck ==  default  (TimeSpan))
   61               {
   62                  _checkWorker =  new   BackgroundWorker();
   63                  _checkWorker.DoWork +=  CheckWorker_DoWork;
   64               }
   65               else 
  66               {
   67                   new  Thread(obj =>
  68                   {
   69                       while  ( true  )
   70                       {
   71                           var  swt =  new   Stopwatch();
   72                           swt.Start();
   73                          CheckWorker_DoWork( null ,  null  );
   74                           swt.Stop();
   75                           Thread.Sleep(timingcheck);
   76                       }
   77                  }) { IsBackground =  true   }.Start();
   78               }
   79  
  80               #endregion 
  81           }
   82  
  83           public   bool  Set( string  key,  byte  [] value)
   84           {
   85               return   Set(key, value, DateTime.Now.Add(Timeout));
   86           }
   87  
  88           public   bool  Set( string  key,  byte  [] value, DateTime effectiveDate)
   89           {
   90               if  (! Enabled)
   91                   return   false  ;
   92  
  93              _readerWriterLock.AcquireWriterLock(- 1  );
   94               try 
  95               {
   96                   if   (_caches.ContainsKey(key))
   97                   {
   98                      _size -=  _caches[key].Length;
   99                      _caches[key] =  value;
  100                      _times[key] =  effectiveDate;
  101                   }
  102                   else 
 103                   {
  104                       _caches.Add(key, value);
  105                       _times.Add(key, effectiveDate);
  106                   }
  107                  _size +=  value.Length;
  108               }
  109               catch  (Exception er)
  110               {
  111                  LogUtil.WriteLog( "  Bytecached.Set  "  , er);
  112                   return   false  ;
  113               }
  114               finally 
 115               {
  116                   _readerWriterLock.ReleaseWriterLock();
  117               }
  118  
 119               #region  检查并清理缓存
 120  
 121               try 
 122               {
  123                   if  (_checkWorker !=  null  && ! _checkWorker.IsBusy)
  124                   {
  125                       _checkWorker.RunWorkerAsync();
  126                   }
  127               }
  128               catch   (Exception er)
  129               {
  130                  LogUtil.WriteLog( "  检查并清理缓存  "  , er);
  131               }
  132  
 133               #endregion 
 134  
 135               return   true  ;
  136           }
  137  
 138           public   byte [] Get( string   key)
  139           {
  140               var  expiry = Timeout == TimeSpan.Zero ?  default  (DateTime) : DateTime.Now.Add(Timeout);
  141               return   Get(key, expiry);
  142           }
  143  
 144           public   byte [] Get( string   key, DateTime effectiveDate)
  145           {
  146               if  (! Enabled)
  147                   return   null  ;
  148  
 149              _readerWriterLock.AcquireReaderLock(- 1  );
  150               var  exist =  false  ;
  151               try 
 152               {
  153                   byte  [] v;
  154                  exist = _caches.TryGetValue(key,  out   v);
  155                   return   v;
  156               }
  157               catch  (Exception er)
  158               {
  159                  LogUtil.WriteLog( "  Bytecached.Get  "  , er);
  160                   return   null  ;
  161               }
  162               finally 
 163               {
  164                   _readerWriterLock.ReleaseReaderLock();
  165                   if  (exist && effectiveDate !=  default  (DateTime))
  166                   {
  167                       #region  刷新缓存
 168  
 169                       new  Thread(obj =>
 170                       {
  171                           var  k = ( string )(( object [])obj)[ 0  ];
  172                           var  edate = (DateTime)(( object [])obj)[ 1  ];
  173                           while  (! Refresh(k, edate))
  174                           {
  175                              Thread.Sleep( 100  );
  176                           }
  177                      }) { IsBackground =  true  }.Start( new   object  []{key, effectiveDate});
  178  
 179                       #endregion 
 180                   }
  181               }
  182           }
  183  
 184           public   bool  ContainsKey( string   key)
  185           {
  186               if  (! Enabled)
  187                   return   false  ;
  188  
 189              _readerWriterLock.AcquireReaderLock(- 1  );
  190               try 
 191               {
  192                   return   _caches.ContainsKey(key);
  193               }
  194               catch  (Exception er)
  195               {
  196                  LogUtil.WriteLog( "  Bytecached.ContainsKey  "  , er);
  197                   return   false  ;
  198               }
  199               finally 
 200               {
  201                   _readerWriterLock.ReleaseReaderLock();
  202               }
  203           }
  204  
 205           public   bool  Refresh( string   key)
  206           {
  207               return  Timeout != TimeSpan.Zero &&  Refresh(key, DateTime.Now.Add(Timeout));
  208           }
  209  
 210           public   bool  Refresh( string   key, DateTime effectiveDate)
  211           {
  212              _readerWriterLock.AcquireWriterLock(- 1  );
  213               try 
 214               {
  215                   if   (_caches.ContainsKey(key))
  216                   {
  217                      _times[key] =  effectiveDate;
  218                   }
  219               }
  220               catch  (Exception er)
  221               {
  222                  LogUtil.WriteLog( "  Bytecached.Refresh  "  , er);
  223                   return   false  ;
  224               }
  225               finally 
 226               {
  227                   _readerWriterLock.ReleaseWriterLock();
  228               }
  229               return   true  ;
  230           }
  231  
 232           public  IList< string >  Keys
  233           {
  234               get 
 235               {
  236                  _readerWriterLock.AcquireReaderLock(- 1  );
  237                   try 
 238                   {
  239                       return   _caches.Keys.ToList();
  240                   }
  241                   catch   (Exception er)
  242                   {
  243                      LogUtil.WriteLog( "  Bytecached.Keys  "  , er);
  244                       return   new  List< string > ();
  245                   }
  246                   finally 
 247                   {
  248                       _readerWriterLock.ReleaseReaderLock();
  249                   }
  250               }
  251           }
  252  
 253           public  ICollection< byte []>  Values
  254           {
  255               get 
 256               {
  257                  _readerWriterLock.AcquireReaderLock(- 1  );
  258                   try 
 259                   {
  260                       return   _caches.Values;
  261                   }
  262                   catch   (Exception er)
  263                   {
  264                      LogUtil.WriteLog( "  Bytecached.Keys  "  , er);
  265                       return   new  List< byte []> ();
  266                   }
  267                   finally 
 268                   {
  269                       _readerWriterLock.ReleaseReaderLock();
  270                   }
  271               }
  272           }
  273  
 274           public  ICollection<DateTime>  Times
  275           {
  276               get 
 277               {
  278                  _readerWriterLock.AcquireReaderLock(- 1  );
  279                   try 
 280                   {
  281                       return   _times.Values;
  282                   }
  283                   catch   (Exception er)
  284                   {
  285                      LogUtil.WriteLog( "  Bytecached.Times  "  , er);
  286                       return   new  Collection<DateTime> ();
  287                   }
  288                   finally 
 289                   {
  290                       _readerWriterLock.ReleaseReaderLock();
  291                   }
  292               }
  293           }
  294  
 295           ///   <summary> 
 296           ///   移除指定数据
  297           ///   </summary> 
 298           ///   <param name="key"></param> 
 299           ///   <returns></returns> 
 300           public   bool  Remove( string   key)
  301           {
  302              _readerWriterLock.AcquireWriterLock(- 1  );
  303               try 
 304               {
  305                   if   (_caches.ContainsKey(key))
  306                   {
  307                      _size -=  _caches[key].Length;
  308                       _caches.Remove(key);
  309                       _times.Remove(key);
  310                   }
  311               }
  312               catch  (Exception er)
  313               {
  314                  LogUtil.WriteLog( "  Bytecached.Remove_key  "  , er);
  315                   return   false  ;
  316               }
  317               finally 
 318               {
  319                   _readerWriterLock.ReleaseWriterLock();
  320               }
  321               return   true  ;
  322           }
  323  
 324           public   void   Clear()
  325           {
  326              _readerWriterLock.AcquireWriterLock(- 1  );
  327               try 
 328               {
  329                  _size =  0  ;
  330                   _caches.Clear();
  331                   _times.Clear();
  332               }
  333               catch  (Exception er)
  334               {
  335                  LogUtil.WriteLog( "  Bytecached.Clear  "  , er);
  336               }
  337               finally 
 338               {
  339                   _readerWriterLock.ReleaseWriterLock();
  340               }
  341           }
  342  
 343           private   void  CheckWorker_DoWork( object   sender, DoWorkEventArgs e)
  344           {
  345              Checking =  true  ;
  346               try 
 347               {
  348                   bool   clearSize;
  349                   bool   collect;
  350                  IEnumerable< string >  clearKeys;
  351                   var  count =  0  ;
  352                   var  swt =  new   Stopwatch();
  353                   var  t =  new   Stopwatch();
  354  
 355                   #region  清理超时记录
 356  
 357                  _readerWriterLock.AcquireReaderLock(- 1  );
  358                   swt.Start();
  359                   try 
 360                   {
  361                      clearKeys =  from  time  in  _times  where  time.Value <= DateTime.Now  orderby  time.Value  select   time.Key;
  362                   }
  363                   finally 
 364                   {
  365                       _readerWriterLock.ReleaseReaderLock();
  366                       swt.Stop();
  367                   }
  368                  Thread.Sleep( 10  );
  369                  _readerWriterLock.AcquireWriterLock(- 1  );
  370                   t.Start();
  371                   swt.Reset();
  372                   swt.Start();
  373                   try 
 374                   {
  375                       foreach  ( var  clearKey  in   clearKeys)
  376                       {
  377                           if  (t.ElapsedMilliseconds >  20  )
  378                           {
  379                               _readerWriterLock.ReleaseWriterLock();
  380                              Thread.Sleep( 10  );
  381                              _readerWriterLock.AcquireWriterLock(- 1  );
  382                               t.Reset();
  383                           }
  384                           if   (_caches.ContainsKey(clearKey))
  385                           {
  386                              _size -=  _caches[clearKey].Length;
  387                               _caches.Remove(clearKey);
  388                               _times.Remove(clearKey);
  389                           }
  390                          count++ ;
  391                       }
  392                   }
  393                   finally 
 394                   {
  395                      clearSize = _size >=  MaxSize;
  396                      collect = count >  0  ||  clearSize;
  397                       _readerWriterLock.ReleaseWriterLock();
  398                       t.Stop();
  399                       swt.Stop();
  400                   }
  401  
 402                   #endregion 
 403  
 404                   if   (clearSize)
  405                   {
  406                       #region  清理超量记录
 407  
 408                      Thread.Sleep( 10  );
  409                      _readerWriterLock.AcquireReaderLock(- 1  );
  410                       swt.Reset();
  411                       swt.Start();
  412                       try 
 413                       {
  414                          clearKeys =  from  time  in  _times  orderby  time.Value  select   time.Key;
  415                       }
  416                       finally 
 417                       {
  418                           _readerWriterLock.ReleaseReaderLock();
  419                           swt.Stop();
  420                       }
  421                      Thread.Sleep( 10  );
  422                      _readerWriterLock.AcquireWriterLock(- 1  );
  423                       t.Reset();
  424                       t.Start();
  425                       swt.Reset();
  426                       swt.Start();
  427                      count =  0  ;
  428                       try 
 429                       {
  430                           var  i =  0  ;
  431                           foreach  ( var  clearKey  in   clearKeys)
  432                           {
  433                               if  (i == ClearCount -  1  )
  434                                  i =  0  ;
  435                               if  (i ==  0  && _size <  MaxSize)
  436                                   break  ;
  437                               if  (t.ElapsedMilliseconds >  20  )
  438                               {
  439                                   _readerWriterLock.ReleaseWriterLock();
  440                                  Thread.Sleep( 10  );
  441                                  _readerWriterLock.AcquireWriterLock(- 1  );
  442                                   t.Reset();
  443                               }
  444                               if   (_caches.ContainsKey(clearKey))
  445                               {
  446                                  _size -=  _caches[clearKey].Length;
  447                                   _caches.Remove(clearKey);
  448                                   _times.Remove(clearKey);
  449                               }
  450                              i++ ;
  451                              count++ ;
  452                           }
  453                       }
  454                       finally 
 455                       {
  456                           _readerWriterLock.ReleaseWriterLock();
  457                           t.Stop();
  458                           swt.Stop();
  459                       }
  460  
 461                       #endregion 
 462                   }
  463  
 464                   if   (collect)
  465                   {
  466                      ThreadPool.QueueUserWorkItem(obj =>  GC.Collect());
  467                   }
  468               }
  469               finally 
 470               {
  471                  Checking =  false  ;
  472               }
  473           }
  474  
 475           public   int   Count
  476           {
  477               get 
 478               {
  479                  _readerWriterLock.AcquireReaderLock(- 1  );
  480                   try 
 481                   {
  482                       return   _caches.Count;
  483                   }
  484                   catch  (Exception er)
  485                   {
  486                      LogUtil.WriteLog( "  Bytecached.Count  "  , er);
  487                       return   0  ;
  488                   }
  489                   finally 
 490                   {
  491                       _readerWriterLock.ReleaseReaderLock();
  492                   }
  493               }
  494           }
  495  
 496           public   long   Size
  497           {
  498               get 
 499               {
  500                  _readerWriterLock.AcquireReaderLock(- 1  );
  501                   try 
 502                   {
  503                       return   _size;
  504                   }
  505                   catch   (Exception er)
  506                   {
  507                      LogUtil.WriteLog( "  Bytecached.Size  "  , er);
  508                       return   0  ;
  509                   }
  510                   finally 
 511                   {
  512                       _readerWriterLock.ReleaseReaderLock();
  513                   }
  514               }
  515           }
  516  
 517           public   object  [][] List
  518           {
  519               get 
 520               {
  521                  _readerWriterLock.AcquireReaderLock(- 1  );
  522                   try 
 523                   {
  524                       return  _caches.Select(obj =>  new   object  [] { obj.Key, obj.Value.Length, _times[obj.Key] }).ToArray();
  525                   }
  526                   catch   (Exception er)
  527                   {
  528                      LogUtil.WriteLog( "  Bytecached.List  "  , er);
  529                       return   new   object [ 3  ][];
  530                   }
  531                   finally 
 532                   {
  533                       _readerWriterLock.ReleaseReaderLock();
  534                   }
  535               }
  536           }
  537  
 538           public   void   Dispose()
  539           {
  540               Clear();
  541           }
  542       }
  543  }

 

 

 

标签:  DSS.NET ,  DFS.NET

作者: Leo_wl

    

出处: http://HdhCmsTestcnblogs测试数据/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于自己封装的内存缓存类DotNet.Caches.Bytecached的详细内容...

  阅读:39次