C# 缓存使用笔记

缓存技术是一大门槛,怎么构造缓存才是奇思妙解。我是这样认为的,因为一提及缓存,相信大家都能说出个一二的。实际操作是另外一回事的。我分享下我们业务可能会用到的场景。

目的就是从缓存中依次或者排队拿出数据,进而解决并发问题。缓存的学习和应用有一段时间了,推荐这个大佬的讲解https://www.cnblogs.com/wuhuacong/p/3526335.html

我的代码:

  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Data;
  5 using System.Drawing;
  6 using System.Linq;
  7 using System.Runtime.Caching;
  8 using System.Text;
  9 using System.Threading.Tasks;
 10 using System.Windows.Forms;
 11 
 12 namespace Test_缓存
 13 {
 14     public partial class Form1 : Form
 15     {
 16         public Form1()
 17         {
 18             InitializeComponent();
 19         }
 20 
 21         List<Emtity> lst = new List<Emtity>();
 22 
 23         private void button1_Click(object sender, EventArgs e)
 24         {
 25 
 26             //for (int i = 0; i < 10; i++)
 27             //{
 28             //Emtity mod=new Emtity();
 29             //string str = UHastable<string>.Instance;
 30             //mod.Id = i+1;
 31             //mod.Name = str;
 32             //lst.Add(mod);
 33             //}
 34 
 35             //Emtity mod = UHastable<Emtity>.Instance;
 36             //lst.Add(mod);
 37 
 38             lst = UHastable<List<Emtity>>.InstanceList;
 39 
 40         }
 41 
 42         private void button2_Click(object sender, EventArgs e)
 43         {
 44             dataGridView1.DataSource = lst;
 45         }
 46 
 47         private void button3_Click(object sender, EventArgs e)
 48         {
 49             GetUserFullName("2");
 50         }
 51 
 52         /// <summary>
 53         /// 根据用户的ID,获取用户的全名,并放到缓存里面
 54         /// </summary>
 55         /// <param name="userId">用户的ID</param>
 56         /// <returns></returns>
 57         public string GetUserFullName(string userId)
 58         {
 59             string key = "Security_UserFullName" + userId;
 60             List<Emtity> lst_s = new List<Emtity>();
 61             Emtity mod = new Emtity();
 62             mod.Name = "333";
 63             lst_s.Add(mod);
 64 
 65             string fullName = MemoryCacheHelper.GetCacheItem<string>(key,
 66                 delegate() { return lst_s[0].Name; },
 67                 new TimeSpan(0, 30, 0)); //30分钟过期
 68             return fullName;
 69         }
 70 
 71         public List<Emtity> GetUsernName()
 72         {
 73             List<Emtity> lst_uuu = new List<Emtity>();
 74             string key = "Security_UserFullName22";
 75             Emtity mod = new Emtity();
 76             mod.Name = "333";
 77             lst_uuu.Add(mod);
 78             MemoryCacheHelper.GetCacheItem<List<Emtity>>(key,
 79                 delegate() { return lst_uuu; },
 80                 new TimeSpan(0, 30, 0)); //30分钟过期
 81             return lst_uuu;
 82         }
 83         string[] str=new string[10];
 84         private int index = 0;
 85         private void button4_Click(object sender, EventArgs e)
 86         {
 87             if (index >= 10)
 88             {
 89                 MessageBox.Show("NO:"+ index.ToString());
 90                 return;
 91             }
 92             for (int i = 0; i < str.Length; i++)
 93             {
 94                 str[i] = "a" + i.ToString();
 95             }
 96             List<Emtity> lst_uuu = MemoryCacheHelper.GetCacheItem<List<Emtity>>(str[index],
 97                 delegate()
 98                 {
 99                     List<Emtity> lst_222 = new List<Emtity>();
100 
101                     Emtity mod = new Emtity();
102                     mod.Id = index;
103                     mod.Name = "333";
104                     lst_222.Add(mod);
105                     return lst_222;
106                 },
107                 new TimeSpan(0, 30, 0)); //30分钟过期
108             index++;
109         }
110 
111         private int count = 0;
112         private void button5_Click(object sender, EventArgs e)
113         {
114             count++;
115             index--;
116            
117             var s = MemoryCache.Default[str[index]];
118             //假设业务需求是取出数据后就移除该数据 则
119             MemoryCache.Default.Remove(str[index]);
120             //让index=10 验证数据是否真正从缓存中移除了
121             if (index == 0) index = 10;
122 
123            
124 
125             if (count >= 10 && count < 20)
126             {
127                 //开始验证缓存中的数据是否为空
128                 if (s == null) MessageBox.Show("OK,该缓存地址为空。str["+ index + "]");
129             }
130             //假设所有缓存地址都为空了,这时可以释放该缓存地址了,也可以保留
131             if (count >= 20)
132             {
133                 MemoryCache.Default.Dispose();
134                 MessageBox.Show("OK,释放由 System.Runtime.Caching.MemoryCache 类的当前实例占用的所有资源。");
135                 return;
136             }
137             //假设要释放index=8时的缓存地址,然后验证下index<8的缓存地址释放有数据
138             if (index <= 8)
139             {
140                 MemoryCache.Default.Dispose();
141                 var s2= (List<Emtity>) MemoryCache.Default[str[index - 1]];
142                 string str55 =
143                     string.Format("OK,释放了缓存地址的值str[{0}],下一个值:str[{1}]={2}", index, index - 1,
144                         s2 != null ? s2[0].Id.ToString() : "null");
145                 MessageBox.Show(str55);
146             }
147         }
148     }
149 
150     public class Emtity
151     {
152         public int Id { get; set; }
153 
154         public string Name { get; set; }
155     }
156 
157 }
View Code

其他类:

MemoryCacheHelper:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Runtime.Caching;
 5 using System.Text;
 6 using System.Threading.Tasks;
 7 
 8 namespace Test_缓存
 9 {
10     public class MemoryCacheHelper
11     {
12         private static readonly  Object _locker=new object();
13         
14         public static T GetCacheItem<T>(String key, Func<T> cachePopulate, TimeSpan? slidingExpiration = null, DateTime? absoluteExpiration = null)
15         {
16             if (String.IsNullOrWhiteSpace(key)) throw new ArgumentException("Invalid cache key");
17             if (cachePopulate == null) throw new ArgumentNullException("cachePopulate");
18             if (slidingExpiration == null && absoluteExpiration == null) throw new ArgumentException("Either a sliding expiration or absolute must be provided");
19             //引用 System.Runtime.Caching  https://docs.microsoft.com/zh-cn/dotnet/api/system.runtime.caching.memorycache?redirectedfrom=MSDN&view=netframework-4.8
20             if (MemoryCache.Default[key] == null)
21             {
22                 lock (_locker)
23                 {
24                     if (MemoryCache.Default[key] == null)
25                     {
26                         var item = new CacheItem(key, cachePopulate());
27                         var policy = CreatePolicy(slidingExpiration, absoluteExpiration);
28 
29                         MemoryCache.Default.Add(item, policy);
30                     }
31                 }
32             }
33 
34             return (T)MemoryCache.Default[key];
35         }
36 
37         private static CacheItemPolicy CreatePolicy(TimeSpan? slidingExpiration, DateTime? absoluteExpiration)
38         {
39             var policy = new CacheItemPolicy();
40 
41             if (absoluteExpiration.HasValue)
42             {
43                 policy.AbsoluteExpiration = absoluteExpiration.Value;
44             }
45             else if (slidingExpiration.HasValue)
46             {
47                 policy.SlidingExpiration = slidingExpiration.Value;
48             }
49 
50             policy.Priority = CacheItemPriority.Default;
51 
52             return policy;
53         }
54     }
55 }
View Code

Reflect:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Threading;
 5 using System.Windows.Forms;
 6 
 7 namespace Test_缓存
 8 {
 9     public class Reflect<T> where T : class
10     {
11         public static T Create()
12         {
13             try
14             {
15                 Random rd=new Random();
16                 Thread.Sleep(10);
17                 //T t = (T)(object)Convert.ToString(rd.Next(0, 9));
18                 Emtity et =new Emtity();
19                 et.Id = 1;
20                 et.Name = "LiuL";
21                 return (T)(object)et;
22             }
23             catch (Exception e)
24             {
25                 MessageBox.Show(e.ToString());
26                 return null;
27             }
28            
29             
30         }
31 
32         public static T Create(int index)
33         {
34             try
35             {
36                 Random rd = new Random();
37                 Thread.Sleep(10);
38                 //T t = (T)(object)Convert.ToString(rd.Next(0, 9));
39                 List<Emtity> lst=new List<Emtity>();
40                 for (int i = 0; i < index; i++)
41                 {
42                     Emtity et = new Emtity();
43                     et.Id = i+1;
44                     et.Name = "LiuL"+ Convert.ToString(rd.Next(0, 9));
45                     lst.Add(et);
46                 }
47                 return (T)(object)lst;
48             }
49             catch (Exception e)
50             {
51                 MessageBox.Show(e.ToString());
52                 return null;
53             }
54 
55 
56         }
57     }
58 
59 }
View Code

UHastable:

 1 using System;
 2 using System.Collections;
 3 using System.Collections.Generic;
 4 using System.Linq;
 5 using System.Text;
 6 using System.Threading.Tasks;
 7 using System.Windows.Forms;
 8 
 9 namespace Test_缓存
10 {
11     public class UHastable<T> where T: class
12     {
13         private  static  Hashtable objCache=new Hashtable();
14         private static object syncRoot = new Object();
15 
16         private static int _Id;
17         public static int Id { get; set; }
18         public static T Instance
19         {
20             get
21             {
22                 //string CacheKey = typeof(T).FullName;
23                 /*T bll= (T)objCache[CacheKey];*/  //从缓存读取  
24                 T bll = (T)objCache[_Id];
25                 if (bll == null)
26                 {
27                     lock (syncRoot)
28                     {
29                         if (bll == null)
30                         {
31                             bll = Reflect<T>.Create();//反射创建,并缓存
32                             objCache.Add(_Id, bll);
33                         }
34                     }
35                 }
36 
37                 _Id++;
38                 return bll;
39             }
40             
41         }
42 
43         public static T InstanceList
44         {
45             get
46             {
47                 T bll = (T)objCache[_Id];
48                 if (bll == null)
49                 {
50                     lock (syncRoot)
51                     {
52                         if (bll == null)
53                         {
54                             bll = Reflect<T>.Create(10);//反射创建,并缓存
55                             objCache.Add(_Id, bll);
56                         }
57                     }
58                 }
59 
60                 _Id++;
61                 return bll;
62             }
63 
64         }
65     }
66 
67     
68 }
View Code

测试数据都是模拟数据。

原文地址:https://www.cnblogs.com/LiuL123-321/p/12204408.html