Redis.cs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. using System.Text;
  2. using CSRedis;
  3. using Microsoft.Extensions.Caching.Distributed;
  4. using Microsoft.Extensions.Caching.Redis;
  5. using Microsoft.Extensions.DependencyInjection;
  6. namespace EasyTemplate.Tool;
  7. public static class Redis
  8. {
  9. /// <summary>
  10. /// 使用缓存
  11. /// </summary>
  12. /// <param name="services"></param>
  13. /// <returns></returns>
  14. public static void AddRedis(this IServiceCollection services)
  15. {
  16. //csredis的两种使用方式
  17. var csredis = new CSRedisClient(Global.CacheConnectionString);
  18. services.AddSingleton(csredis);
  19. RedisHelper.Initialization(csredis);
  20. //基于redis初始化IDistributedCache
  21. services.AddSingleton<IDistributedCache>(new CSRedisCache(csredis));
  22. Global.Redis = csredis;
  23. }
  24. /// <summary>
  25. ///
  26. /// </summary>
  27. /// <typeparam name="T"></typeparam>
  28. /// <param name="cacheKey"></param>
  29. /// <returns></returns>
  30. public static async Task<bool> ExistsAsync(string cacheKey)
  31. {
  32. return await Global.Redis.ExistsAsync(cacheKey);
  33. }
  34. /// <summary>
  35. /// 获取缓存
  36. /// </summary>
  37. /// <typeparam name="T"></typeparam>
  38. /// <param name="cacheKey"></param>
  39. /// <returns></returns>
  40. public static async Task<T> GetAsync<T>(string cacheKey)
  41. {
  42. var res = await Global.Redis.GetAsync(cacheKey);
  43. return res == null ? default : res.ToEntity<T>();
  44. }
  45. /// <summary>
  46. /// 设置缓存
  47. /// </summary>
  48. /// <param name="cacheKey"></param>
  49. /// <param name="value"></param>
  50. /// <param name="time"></param>
  51. /// <returns></returns>
  52. public static async Task SetAsync(string cacheKey, object value, long time = 604800)
  53. {
  54. await Global.Redis.SetAsync(cacheKey, Encoding.UTF8.GetBytes(value.ToJson()), (int)time);
  55. }
  56. /// <summary>
  57. /// 数据自增等操作,基于分布式锁,解决并发问题
  58. /// </summary>
  59. /// <param name="lockKey">标识,用于确认哪一条数据</param>
  60. /// <param name="key">键</param>
  61. /// <param name="value">值</param>
  62. /// <returns></returns>
  63. public static async Task SetWithLockAsync(string lockKey, string key, object value)
  64. {
  65. var id = Guid.NewGuid().ToString("N");
  66. var start = DateTime.Now;
  67. while (true)
  68. {
  69. //设置锁1秒后过期
  70. var success = RedisHelper.Set(lockKey, id, expireSeconds: 1, exists: RedisExistence.Nx);
  71. if (success) break;
  72. //超出2秒立即跳出,防止阻塞
  73. if (DateTime.Now.Subtract(start).TotalSeconds >= 2)
  74. break;
  75. }
  76. try
  77. {
  78. await SetAsync(key, value);
  79. }
  80. catch { }
  81. finally
  82. {
  83. RedisHelper.Eval("if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end", lockKey, id);//释放锁的redis脚本
  84. }
  85. }
  86. }