• 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

    测试数据都是模拟数据。

  • 相关阅读:
    数据库专题(SQLServer、MySQL)
    第九节:IdentityServer4简介及客户端模式和用户密码模式的应用
    第八节:理解认证和授权、Oauth2.0及四种授权模式、OpenId Connect
    第七节:基于Ocelot网关层的微服务校验(手写jwt校验中间件和利用IdentityModel.Tokens.Jwt校验)
    第六节:Ocelot集成Polly熔断降级,以及缓存、限流、自身负载等其它功能
    第五节:基于Ocelot网关简介、路由功能、集成Consul使用
    第四节:Polly基于控制台和Web端用法(熔断、降级、重试、超时处理等)
    第三节:基于Consul做服务的配置中心
    第二节:Consul简介及服务注册、发现、健康检查
    第一节:微服务准备(Webapi复习、PostMan的使用、项目启动方式、业务代码准备)
  • 原文地址:https://www.cnblogs.com/LiuL123-321/p/12204408.html
Copyright © 2020-2023  润新知