基于ConcurrentDictionary, Delegate 定时刷新 缓存基础数据,提高性能
1 public interface ICacheManager 2 { 3 object GetFromCache(string key); 4 void AddToCache(string key, TimeSpan expireTimeSpan, RefreshObjectDelegate refreshObjectDelegate); 5 }
1 public class CacheManager : ICacheManager 2 { 3 private readonly ConcurrentDictionary<string, CacheObject> _cache = new ConcurrentDictionary<string, CacheObject>(); 4 private static readonly object _lock = new object(); 5 public void AddToCache(string key, TimeSpan expireTimeSpan, RefreshObjectDelegate refreshObjectDelegate) 6 { 7 if (!_cache.TryGetValue(key, out CacheObject o)) 8 { 9 // check if the key exist or not; if no, then add it 10 CacheObject cacheObject = new CacheObject() { TimeOutSpan = expireTimeSpan, ExpireTime = DateTime.Now + expireTimeSpan, RefreshObjectDelegate = refreshObjectDelegate}; 11 cacheObject.Value = cacheObject.RefreshObjectDelegate(); 12 _cache[key] = cacheObject; 13 } 14 } 15 16 public object GetFromCache(string key) 17 { 18 if (!_cache.TryGetValue(key, out CacheObject o)) return null; 19 if (DateTime.Now < o.ExpireTime && o.Value != null) 20 { 21 return o.Value; 22 } 23 else 24 { 25 //async or mul-thread 26 lock(_lock) 27 { 28 if (DateTime.Now < o.ExpireTime && o.Value!=null) 29 { 30 return o.Value; 31 } 32 try 33 { 34 //get the data again, when it's expired 35 object newObject = o.RefreshObjectDelegate(); 36 if ( newObject == null ) 37 { 38 //if get data fails, return the old data and set the expiry time 1 min later 39 o.ExpireTime = DateTime.Now+ TimeSpan.FromMinutes(1); 40 return o.Value; 41 } 42 //if get data successfully, return the fresh data and set the expiry time TimeOutSpan later 43 o.Value = newObject; 44 o.ExpireTime = DateTime.Now + o.TimeOutSpan; 45 return newObject; 46 } 47 catch 48 { 49 //if get data fails, return the old data and set the expiry time 1 min later 50 o.ExpireTime = DateTime.Now + TimeSpan.FromMinutes(1); 51 return o.Value; 52 } 53 } 54 } 55 } 56 } 57 58 public delegate object RefreshObjectDelegate(); 59 60 public class CacheObject 61 { 62 /// <summary> 63 /// Store the data 64 /// </summary> 65 public object Value { get; set; } 66 public TimeSpan TimeOutSpan { get; set; } 67 public DateTime ExpireTime { get; set; } 68 69 public RefreshObjectDelegate RefreshObjectDelegate; 70 }
1 public interface IStudent 2 { 3 List<string> GetAllStudents(); 4 }
1 public class Student : IStudent 2 { 3 private readonly ICacheManager _cacheManager; 4 private const string CACHEKEY_STUDENT = "STUDENT"; 5 public Student(ICacheManager cacheManager) 6 { 7 _cacheManager = cacheManager; 8 AddStudentToCache(); 9 } 10 11 private void AddStudentToCache() 12 { 13 RefreshObjectDelegate refreshObjectDelegate = new RefreshObjectDelegate(GetAllStudentsFromDB); 14 //set expire time is 30 min 15 _cacheManager.AddToCache(CACHEKEY_STUDENT,TimeSpan.FromMinutes(30), refreshObjectDelegate); 16 } 17 private List<string> GetAllStudentsFromDB() { 18 //get data 19 List<string> list = new List<string>(); 20 return list; 21 } 22 public List<string> GetAllStudents() 23 { 24 return (List<string>) _cacheManager.GetFromCache(CACHEKEY_STUDENT); 25 } 26 }