自己封装的内存缓存类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的详细内容...
声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://haodehen.cn/did46062