基于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     }

 

posted @ 2023-12-05 15:25  王小二不在家  阅读(23)  评论(0编辑  收藏  举报