.NET Redis简单使用

 1 static void Main(string[] args)
 2         {
 3             var redis = new Redis();
 4             Console.WriteLine("-----------单个设置缓存开始-----------");
 5             redis.Set("a", "123");
 6             Console.WriteLine("a = 123");
 7             redis.Set("b", "456");
 8             Console.WriteLine("b = 456");
 9             redis.Set("c", "789");
10             Console.WriteLine("c = 789");
11             Console.WriteLine("-----------单个设置缓存结束-----------");
12 
13             Thread.Sleep(3000);
14 
15             Console.WriteLine();
16 
17             Console.WriteLine("-----------单个读取缓存开始-----------");
18             Console.WriteLine($"a = {redis.Get<string>("a")}");
19             Console.WriteLine($"b = {redis.Get<string>("b")}");
20             Console.WriteLine($"c = {redis.Get<string>("c")}");
21             Console.WriteLine("-----------单个读取缓存结束-----------");
22 
23             Console.WriteLine();
24 
25             Console.WriteLine("-----------批量读取缓存开始-----------");
26             var arr = new string[] { "a", "b", "c" };
27             var value = redis.BatchGet<string>(arr);
28             for (int i = 0; i < value.Count; i++)
29             {
30                 Console.WriteLine(arr[i] + " = " + value[i]);
31             }
32             Console.WriteLine("-----------批量读取缓存结束-----------");
33 
34             Console.WriteLine();
35 
36             Console.WriteLine("-----------批量设置缓存开始-----------");
37             var modelList = new List<BatchSetModel>
38             {
39                 new BatchSetModel { key = "a", value = "147" },
40                 new BatchSetModel { key = "b", value = "258" },
41                 new BatchSetModel { key = "c", value = "369" }
42             };
43             redis.BatchSet(modelList);
44 
45             //redis.Set("a", "147");
46             //redis.Set("b", "258");
47             //redis.Set("c", "369");
48 
49             Console.WriteLine("a = 147");
50             Console.WriteLine("b = 258");
51             Console.WriteLine("c = 369");
52             Console.WriteLine("-----------批量设置缓存结束-----------");
53 
54             Console.WriteLine();
55             Thread.Sleep(3000);
56             Console.WriteLine("-----------批量读取缓存开始-----------");
57             arr = new string[] { "a", "b", "c" };
58             value = redis.BatchGet<string>(arr);
59             for (int i = 0; i < value.Count; i++)
60             {
61                 Console.WriteLine(arr[i] + " = " + value[i]);
62             }
63             Console.WriteLine("-----------批量读取缓存结束-----------");
64 
65         }

 

<add key="Connection_Redis" value="127.0.0.1:6379,password=123456,abortConnect=false" />
<add key="Connection_Redis_Prefix" value="Test:" />

    public class Redis {
        public Redis() {
            ConnectionString = ConfigurationManager.AppSettings["Connection_Redis"];
            KeyPrefix = ConfigurationManager.AppSettings["Connection_Redis_Prefix"];
        }
        private string ConnectionString { get; set; }

        private string KeyPrefix { get; set; }

        /// <summary>
        /// 并发锁
        /// </summary>
        private static object locker = new object();

        private ConnectionMultiplexer multiplexer = null;

        private ConnectionMultiplexer ConnMultiplexer
        {
            get
            {
                if (multiplexer == null)
                {
                    lock (locker)
                    {
                        multiplexer = CreateMultiplexer();

                        multiplexer.ConnectionFailed += Multiplexer_ConnectionFailed;
                        multiplexer.ConnectionRestored += Multiplexer_ConnectionRestored;
                        multiplexer.ErrorMessage += Multiplexer_ErrorMessage;
                        multiplexer.ConfigurationChanged += Multiplexer_ConfigurationChanged;
                        multiplexer.HashSlotMoved += Multiplexer_HashSlotMoved;
                        multiplexer.InternalError += Multiplexer_InternalError;

                    }
                }

                return multiplexer;
            }
        }

        /// <summary>
        /// 创建连接
        /// </summary>
        /// <returns></returns>
        protected virtual ConnectionMultiplexer CreateMultiplexer()
        {
            ConfigurationOptions config = ConfigurationOptions.Parse(ConnectionString);
            config.ConnectTimeout = 15000;
            config.SyncTimeout = 15000;
            config.AbortOnConnectFail = false;  //失败自动重连

            return ConnectionMultiplexer.Connect(config);
        }

        /// <summary>
        /// 获取内存数据库,从 GetDatabase 方法返回的对象是一个轻量级直通对象,不需要进行存储。
        /// </summary>
        /// <returns></returns>
        private IDatabase GetDatabase()
        {
            return ConnMultiplexer.GetDatabase();
        }
        
#region 注册事件

        /// <summary>
        /// 连接失败时触发,如果重新连接成功你将不会收到这个通知
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected virtual void Multiplexer_ConnectionFailed(object sender, ConnectionFailedEventArgs e)
        {
            //LogHelper.Error("Redis连接失败", e.Exception);
        }

        /// <summary>
        /// 重新连接时通知
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected virtual void Multiplexer_ConnectionRestored(object sender, ConnectionFailedEventArgs e)
        {
            //LogHelper.Error("Redis重新连接成功");
        }

        /// <summary>
        /// 服务端返回错误消息时触发
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected virtual void Multiplexer_ErrorMessage(object sender, RedisErrorEventArgs e)
        {
            //LogHelper.Error($"Redis服务端返回错误:{e.Message}");
        }

        /// <summary>
        /// 配置更改时触发
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected virtual void Multiplexer_ConfigurationChanged(object sender, EndPointEventArgs e)
        {
            //LogHelper.Error($"Redis连接配置更改");
        }

        /// <summary>
        /// 更改集群时触发
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected virtual void Multiplexer_HashSlotMoved(object sender, HashSlotMovedEventArgs e)
        {
            //LogHelper.Error($"Redis集群更改更改");
        }

        /// <summary>
        /// 发生内部错误时触发
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected virtual void Multiplexer_InternalError(object sender, InternalErrorEventArgs e)
        {
            //LogHelper.Error("Redis发生内部错误", e.Exception);
        }
        #endregion
注册事件
       
#region 普通类型

        /// <summary>
        /// 根据key获取缓存对象
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="key">关键字</param>
        /// <returns></returns>
        public virtual T Get<T>(string key)
        {
            return Deserialize<T>(GetDatabase().StringGet(MergeKey(key)));
        }

        /// <summary>
        /// 根据多个关键字获取多个缓存对象
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="keys">关键字数组</param>
        /// <returns></returns>
        public virtual List<T> Get<T>(string[] keys)
        {
            if (keys == null || keys.Length == 0)
            {
                return null;
            }

            List<RedisKey> keyList = new List<RedisKey>();
            foreach (string key in keys)
            {
                keyList.Add(MergeKey(key));
            }

            return Deserialize<T>(GetDatabase().StringGet(keyList.ToArray()));
        }
        /// <summary>
        /// 根据多个关键字批量缓存对象
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="keys">关键字数组</param>
        /// <returns></returns>
        public virtual List<T> BatchGet<T>(string[] keys)
        {
            if (keys == null || keys.Length == 0)
            {
                return null;
            }

            var batch = GetDatabase().CreateBatch();
            //批量读
            List<Task<RedisValue>> taskList = new List<Task<RedisValue>>();
            foreach (string key in keys)
            {

                Task<RedisValue> tres = batch.StringGetAsync(MergeKey(key));
                taskList.Add(tres);
            }
            batch.Execute();


            List<RedisValue> valueList = new List<RedisValue>();
            foreach (var redisValue in taskList)
            {
                valueList.Add(redisValue.Result);//取出对应的value值
            }


            return Deserialize<T>(valueList.ToArray());
        }


        /// <summary>
        /// 设置缓存
        /// </summary>
        /// <param name="key">关键字</param>
        /// <param name="value">值对象</param>
        /// <param name="expiry">留空则默认保留3天</param>
        /// <returns>设置是否成功</returns>
        public virtual bool Set<T>(string key, T value, TimeSpan? expiry = null)
        {
            if (expiry == null)
            {
                expiry = TimeSpan.FromDays(3);
            }

            return GetDatabase().StringSet(MergeKey(key), Serialize(value), expiry);
        }

        /// <summary>
        /// 批量设置缓存
        /// </summary>
        public virtual void BatchSet(List<BatchSetModel> model)
        {
            var batch = GetDatabase().CreateBatch();

            List<Task<bool>> taskList = new List<Task<bool>>();

            //批量写
            foreach (var item in model)
            {
                taskList.Add(batch.StringSetAsync(MergeKey(item.key), Serialize(item.value), item.expiry));
            }
            batch.Execute();
            Task.WaitAll(taskList.ToArray());
        }

        public class BatchSetModel
        {
            public string key { get; set; }

            public RedisValue value { get; set; }

            public TimeSpan? expiry { get; set; }
        }

        /// <summary>
        /// 为数字增长val
        /// </summary>
        /// <param name="key">关键字</param>
        /// <param name="val">增长的值,可以为负</param>
        /// <returns>增长后的值</returns>
        public long Increment(string key, long val = 1)
        {
            return GetDatabase().StringIncrement(MergeKey(key), val);
        }

        /// <summary>
        /// 为数字减少val
        /// </summary>
        /// <param name="key">关键字</param>
        /// <param name="val">减少的值,可以为负</param>
        /// <returns>减少后的值</returns>
        public long StringDecrement(string key, long val = 1)
        {
            return GetDatabase().StringDecrement(MergeKey(key), val);
        }

        #endregion 普通类型
普通类型
     
#region List类型

        /// <summary>
        /// 移除指定ListId的内部List的值
        /// </summary>
        /// <param name="key">关键字</param>
        /// <param name="value">列表内部的值</param>
        /// <returns>移除的个数</returns>
        public long ListRemove<T>(string key, T value)
        {
            return GetDatabase().ListRemove(MergeKey(key), Serialize(value));
        }

        /// <summary>
        /// 获取指定key的List
        /// </summary>
        /// <param name="key">关键字</param>
        /// <returns></returns>
        public List<T> ListRange<T>(string key)
        {
            List<T> result = new List<T>();
            var values = GetDatabase().ListRange(MergeKey(key));
            return Deserialize<T>(values);
        }

        /// <summary>
        /// 入队
        /// </summary>
        /// <param name="key">关键字</param>
        /// <param name="value"></param>
        /// <returns>入队后的队列长度</returns>
        public long ListRightPush<T>(string key, T value)
        {
            return GetDatabase().ListRightPush(MergeKey(key), Serialize(value));
        }

        /// <summary>
        /// 出队/出栈
        /// </summary>
        /// <param name="key">关键字</param>
        /// <returns>出队/队栈的对象,如果key不存在,返回null</returns>
        public T ListLeftPop<T>(string key)
        {
            var value = GetDatabase().ListLeftPop(MergeKey(key));
            return Deserialize<T>(value);
        }

        /// <summary>
        /// 入栈
        /// </summary>
        /// <param name="key">关键字</param>
        /// <param name="value"></param>
        /// <returns>入栈后的队列长度</returns>
        public long ListLeftPush<T>(string key, T value)
        {
            return GetDatabase().ListLeftPush(MergeKey(key), Serialize(value));
        }

        /// <summary>
        /// 获取集合中的数量
        /// </summary>
        /// <param name="key">关键字</param>
        /// <returns></returns>
        public long ListLength(string key)
        {
            return GetDatabase().ListLength(MergeKey(key));
        }

        #endregion List类型
List类型
     
#region Hash类型

        /// <summary>
        /// 判断某个数据是否已经被缓存
        /// </summary>
        /// <param name="key">关键字</param>
        /// <param name="dataKey">数据关键字</param>
        /// <returns></returns>
        public bool HashExists(string key, string dataKey)
        {
            return GetDatabase().HashExists(MergeKey(key), dataKey);
        }

        /// <summary>
        /// 存储数据到hash表
        /// </summary>
        /// <param name="key">关键字</param>
        /// <param name="dataKey">数据关键字</param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool HashSet<T>(string key, string dataKey, T value)
        {
            return GetDatabase().HashSet(MergeKey(key), dataKey, Serialize(value));
        }

        /// <summary>
        /// 移除hash中的某值
        /// </summary>
        /// <param name="key">关键字</param>
        /// <param name="dataKey">数据关键字</param>
        /// <returns></returns>
        public bool HashDelete(string key, string dataKey)
        {
            return GetDatabase().HashDelete(MergeKey(key), dataKey);
        }

        /// <summary>
        /// 移除hash中的多个值
        /// </summary>
        /// <param name="key">关键字</param>
        /// <param name="dataKeys">数据关键字集合</param>
        /// <returns></returns>
        public long HashDelete(string key, List<string> dataKeys)
        {
            return GetDatabase().HashDelete(MergeKey(key), dataKeys.Select(f => (RedisValue)f).ToArray());
        }

        /// <summary>
        /// 从hash表获取数据
        /// </summary>
        /// <param name="key">关键字</param>
        /// <param name="dataKey">数据关键字</param>
        /// <returns></returns>
        public T HashGet<T>(string key, string dataKey)
        {
            var value = GetDatabase().HashGet(MergeKey(key), dataKey);
            return Deserialize<T>(value);
        }

        /// <summary>
        /// 从hash表批量获取数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key">关键字</param>
        /// <param name="dataKeys">数据关键字集合</param>
        /// <returns></returns>
        public List<T> HashGet<T>(string key, string[] dataKeys)
        {
            if (dataKeys == null || dataKeys.Length == 0)
            {
                return null;
            }

            List<RedisValue> keyList = new List<RedisValue>();
            foreach (string item in dataKeys)
            {
                keyList.Add(item);
            }

            return Deserialize<T>(GetDatabase().HashGet(MergeKey(key), keyList.ToArray()));
        }

        /// <summary>
        /// 为数字增长val
        /// </summary>
        /// <param name="key">关键字</param>
        /// <param name="dataKey">数据关键字</param>
        /// <param name="val">可以为负</param>
        /// <returns>增长后的值</returns>
        public long HashIncrement(string key, string dataKey, long val = 1)
        {
            return GetDatabase().HashIncrement(MergeKey(key), dataKey, val);
        }

        /// <summary>
        /// 为数字减少val
        /// </summary>
        /// <param name="key">关键字</param>
        /// <param name="dataKey">数据关键字</param>
        /// <param name="val">可以为负</param>
        /// <returns>减少后的值</returns>
        public long HashDecrement(string key, string dataKey, long val = 1)
        {
            return GetDatabase().HashDecrement(MergeKey(key), dataKey, val);
        }

        /// <summary>
        /// 获取hash表所有key
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key">关键字</param>
        /// <returns></returns>
        public List<T> HashKeys<T>(string key)
        {
            RedisValue[] values = GetDatabase().HashKeys(MergeKey(key));
            return Deserialize<T>(values);
        }

        #endregion Hash类型
Hash类型
     
#region 发布/订阅

        /// <summary>
        /// 订阅(客户端连接可使用KeepAlive=60来发送心跳包保持socket接口活跃)
        /// </summary>
        /// <param name="subChannel"></param>
        /// <param name="handler"></param>
        public void Subscribe(string subChannel, Action<RedisChannel, RedisValue> handler = null)
        {
            ISubscriber sub = ConnMultiplexer.GetSubscriber();
            sub.Subscribe(subChannel, (channel, message) =>
            {
                if (handler == null)
                {
                    Console.WriteLine(subChannel + " 订阅收到消息:" + message);
                }
                else
                {
                    handler(channel, message);
                }
            });
        }

        /// <summary>
        /// 发布
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="channel"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public long Publish<T>(string channel, T msg)
        {
            ISubscriber sub = ConnMultiplexer.GetSubscriber();
            return sub.Publish(channel, JsonConvert.SerializeObject(msg));
        }

        /// <summary>
        /// 取消订阅
        /// </summary>
        /// <param name="channel"></param>
        public void Unsubscribe(string channel)
        {
            ISubscriber sub = ConnMultiplexer.GetSubscriber();
            sub.Unsubscribe(channel);
        }

        /// <summary>
        /// 取消全部订阅
        /// </summary>
        public void UnsubscribeAll()
        {
            ISubscriber sub = ConnMultiplexer.GetSubscriber();
            sub.UnsubscribeAll();
        }

        #endregion 发布/订阅
发布订阅
      
#region Key管理

        /// <summary>
        /// 拼接Key前缀,可多系统使用同一库
        /// </summary>
        /// <param name="key">关键字</param>
        /// <returns></returns>
        private string MergeKey(string key)
        {
            if (string.IsNullOrEmpty(KeyPrefix))
            {
                return key;
            }

            return KeyPrefix + key;
        }

        /// <summary>
        /// 判断在缓存中是否存在该key的缓存数据
        /// </summary>
        /// <param name="key">关键字</param>
        /// <returns>关键字是否存在</returns>
        public virtual bool Exists(string key)
        {
            return GetDatabase().KeyExists(MergeKey(key));  //可直接调用
        }

        /// <summary>
        /// 移除指定key的缓存
        /// </summary>
        /// <param name="key">关键字</param>
        /// <returns>是否移除成功</returns>
        public virtual bool Remove(string key)
        {
            return GetDatabase().KeyDelete(MergeKey(key));
        }

        /// <summary>
        /// 移除指定key的缓存
        /// </summary>
        /// <param name="keys">关键字数组</param>
        /// <returns>移除的缓存数</returns>
        public virtual long Remove(string[] keys)
        {
            RedisKey[] redisKeys = keys.Select(f => (RedisKey)MergeKey(f)).ToArray();
            return GetDatabase().KeyDelete(redisKeys);
        }

        /// <summary>
        /// 设置Key的时间
        /// </summary>
        /// <param name="key">关键字</param>
        /// <param name="expiry">留空则默认保留3天</param>
        /// <returns></returns>
        public virtual bool SetExpire(string key, TimeSpan? expiry = null)
        {
            if (expiry == null)
            {
                expiry = TimeSpan.FromDays(3);
            }

            return GetDatabase().KeyExpire(MergeKey(key), expiry);
        }

        #endregion Key管理
Key管理
     
#region 序列/反序列

        /// <summary>
        /// 序列化对象
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        private string Serialize<T>(T value)
        {
            return JsonConvert.SerializeObject(value);
        }

        /// <summary>
        /// 反序列化对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="value"></param>
        /// <returns></returns>
        private static T Deserialize<T>(RedisValue value)
        {
            if (value.HasValue)
            {
                return JsonConvert.DeserializeObject<T>(value);
            }

            return default;
        }

        /// <summary>
        /// 反序列化对象(返回值可能为null,需要根据数据类型判空)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="values"></param>
        /// <returns></returns>
        private static List<T> Deserialize<T>(RedisValue[] values)
        {
            List<T> result = new List<T>();

            foreach (var item in values)
            {
                var model = Deserialize<T>(item);
                result.Add(model);
            }

            return result;
        }

        #endregion 序列/反序列
序列/反序列
   }

 

https://www.cnblogs.com/cang12138/p/8884362.html 这边稍微简短点

posted @ 2021-02-01 16:41  LIGHTPRO  阅读(436)  评论(0编辑  收藏  举报