你的位置:首页 > ASP.net教程

[ASP.net教程]StackExchange.Redis通用封装类分享


  前两天朋友问我,有没有使用过StackExchange.Redis,问我要个封装类,由于之前都是使用ServiceStack.Redis,由于ServiceStack.Redis v4版本后是收费版的,所以现在也很有公司都在使用StackExchange.Redis而抛弃ServiceStack.Redis了。其实个人觉得,两个驱动都不错,只是由于ServiceStack.Redis收费导致目前很多公司都是基于V3版本的使用,也有人说V3版本有很多Bug,没有维护和升级,不过至少目前我是没发现Bug。

  不过ServiceStack.Redis同StackExchange.Redis比较,抛开收费的来说,确认比StackExchange.Redis 更有优势。StackExchange.Redis国内文档很少,不要说国内的文档了,连github上面对应的介绍文档都是很片面,这点我真的觉得StackExchange.Redis的作者至少要完善下文档,很多都是要看源码的例子才有。网上对StackExchange.Redis的使用例子也比ServiceStack.Redis少得多,不是说没人用,只是我查来查去,大部分都是基于String类型的数据进行使用的封装类,对于List,SortedSet,Hash的封装操作都很少,基本都是东写一点,西写一点,很难找到完整的。在参考了一些文章和源码后,这里提供一个自己封装的类,基本提供对于各种类型的使用封装,提供给大家学习使用,如果有哪里写的不好的,大家也可以互相交流。

  首先是 ConnectionMultiplexer 的封装,ConnectionMultiplexer对象是StackExchange.Redis最中枢的对象。这个类的实例需要被整个应用程序域共享和重用的,所以不需要在每个操作中不停的创建该对象的实例,一般都是使用单例来创建和存放这个对象,这个在官网上也有说明。

  ConnectionMultiplexer 封装

 1 /// <summary> 2   /// ConnectionMultiplexer对象管理帮助类 3   /// </summary> 4   public static class RedisConnectionHelp 5   { 6     //系统自定义Key前缀 7     public static readonly string SysCustomKey = ConfigurationManager.AppSettings["redisKey"] ?? ""; 8  9     //"127.0.0.1:6379,allowadmin=true 10     private static readonly string RedisConnectionString = ConfigurationManager.ConnectionStrings["RedisExchangeHosts"].ConnectionString; 11  12     private static readonly object Locker = new object(); 13     private static ConnectionMultiplexer _instance; 14     private static readonly ConcurrentDictionary<string, ConnectionMultiplexer> ConnectionCache = new ConcurrentDictionary<string, ConnectionMultiplexer>(); 15  16     /// <summary> 17     /// 单例获取 18     /// </summary> 19     public static ConnectionMultiplexer Instance 20     { 21       get 22       { 23         if (_instance == null) 24         { 25           lock (Locker) 26           { 27             if (_instance == null || !_instance.IsConnected) 28             { 29               _instance = GetManager(); 30             } 31           } 32         } 33         return _instance; 34       } 35     } 36  37     /// <summary> 38     /// 缓存获取 39     /// </summary> 40     /// <param name="connectionString"></param> 41     /// <returns></returns> 42     public static ConnectionMultiplexer GetConnectionMultiplexer(string connectionString) 43     { 44       if (!ConnectionCache.ContainsKey(connectionString)) 45       { 46         ConnectionCache[connectionString] = GetManager(connectionString); 47       } 48       return ConnectionCache[connectionString]; 49     } 50  51     private static ConnectionMultiplexer GetManager(string connectionString = null) 52     { 53       connectionString = connectionString ?? RedisConnectionString; 54       var connect = ConnectionMultiplexer.Connect(connectionString); 55  56       //注册如下事件 57       connect.ConnectionFailed += MuxerConnectionFailed; 58       connect.ConnectionRestored += MuxerConnectionRestored; 59       connect.ErrorMessage += MuxerErrorMessage; 60       connect.ConfigurationChanged += MuxerConfigurationChanged; 61       connect.HashSlotMoved += MuxerHashSlotMoved; 62       connect.InternalError += MuxerInternalError; 63  64       return connect; 65     } 66  67     #region 事件 68  69     /// <summary> 70     /// 配置更改时 71     /// </summary> 72     /// <param name="sender"></param> 73     /// <param name="e"></param> 74     private static void MuxerConfigurationChanged(object sender, EndPointEventArgs e) 75     { 76       Console.WriteLine("Configuration changed: " + e.EndPoint); 77     } 78  79     /// <summary> 80     /// 发生错误时 81     /// </summary> 82     /// <param name="sender"></param> 83     /// <param name="e"></param> 84     private static void MuxerErrorMessage(object sender, RedisErrorEventArgs e) 85     { 86       Console.WriteLine("ErrorMessage: " + e.Message); 87     } 88  89     /// <summary> 90     /// 重新建立连接之前的错误 91     /// </summary> 92     /// <param name="sender"></param> 93     /// <param name="e"></param> 94     private static void MuxerConnectionRestored(object sender, ConnectionFailedEventArgs e) 95     { 96       Console.WriteLine("ConnectionRestored: " + e.EndPoint); 97     } 98  99     /// <summary>100     /// 连接失败 , 如果重新连接成功你将不会收到这个通知101     /// </summary>102     /// <param name="sender"></param>103     /// <param name="e"></param>104     private static void MuxerConnectionFailed(object sender, ConnectionFailedEventArgs e)105     {106       Console.WriteLine("重新连接:Endpoint failed: " + e.EndPoint + ", " + e.FailureType + (e.Exception == null ? "" : (", " + e.Exception.Message)));107     }108 109     /// <summary>110     /// 更改集群111     /// </summary>112     /// <param name="sender"></param>113     /// <param name="e"></param>114     private static void MuxerHashSlotMoved(object sender, HashSlotMovedEventArgs e)115     {116       Console.WriteLine("HashSlotMoved:NewEndPoint" + e.NewEndPoint + ", OldEndPoint" + e.OldEndPoint);117     }118 119     /// <summary>120     /// redis类库错误121     /// </summary>122     /// <param name="sender"></param>123     /// <param name="e"></param>124     private static void MuxerInternalError(object sender, InternalErrorEventArgs e)125     {126       Console.WriteLine("InternalError:Message" + e.Exception.Message);127     }128 129     #endregion 事件130   }

  RedisHelper 通用操作类封装

 1  public class RedisHelper 2   { 3     private int DbNum { get; } 4     private readonly ConnectionMultiplexer _conn; 5     public string CustomKey; 6  7     #region 构造函数 8  9     public RedisHelper(int dbNum = 0)10         : this(dbNum, null)11     {12     }13 14     public RedisHelper(int dbNum, string readWriteHosts)15     {16       DbNum = dbNum;17       _conn =18         string.IsNullOrWhiteSpace(readWriteHosts) ?19         RedisConnectionHelp.Instance :20         RedisConnectionHelp.GetConnectionMultiplexer(readWriteHosts);21     }22 23      private string AddSysCustomKey(string oldKey)24     {25       var prefixKey = CustomKey ?? RedisConnectionHelp.SysCustomKey;26       return prefixKey + oldKey;27     }28 29     private T Do<T>(Func<IDatabase, T> func)30     {31       var database = _conn.GetDatabase(DbNum);32       return func(database);33     }34 }

  其中CustomKey用来表示系统前缀,AddSysCustomKey方法对每个key都进行前缀的添加处理,这里推荐大家在命名redis的key的时候最好的加上前缀,并且使用 :来分割前缀 ,这里在使用可视化工具查看的时候就比较好区分,比如我的的前缀是 Demo:test:(一般是  系统名:业务名:),然后你查看的时候你会发现整齐,好区分了很多

 

  String类型的封装

 

 1     #region String 2  3     #region 同步方法 4  5     /// <summary> 6     /// 保存单个key value 7     /// </summary> 8     /// <param name="key">Redis Key</param> 9     /// <param name="value">保存的值</param> 10     /// <param name="expiry">过期时间</param> 11     /// <returns></returns> 12     public bool StringSet(string key, string value, TimeSpan? expiry = default(TimeSpan?)) 13     { 14       key = AddSysCustomKey(key); 15       return Do(db => db.StringSet(key, value, expiry)); 16     } 17  18     /// <summary> 19     /// 保存多个key value 20     /// </summary> 21     /// <param name="keyValues">键值对</param> 22     /// <returns></returns> 23     public bool StringSet(List<KeyValuePair<RedisKey, RedisValue>> keyValues) 24     { 25       List<KeyValuePair<RedisKey, RedisValue>> newkeyValues = 26         keyValues.Select(p => new KeyValuePair<RedisKey, RedisValue>(AddSysCustomKey(p.Key), p.Value)).ToList(); 27       return Do(db => db.StringSet(newkeyValues.ToArray())); 28     } 29  30     /// <summary> 31     /// 保存一个对象 32     /// </summary> 33     /// <typeparam name="T"></typeparam> 34     /// <param name="key"></param> 35     /// <param name="obj"></param> 36     /// <param name="expiry"></param> 37     /// <returns></returns> 38     public bool StringSet<T>(string key, T obj, TimeSpan? expiry = default(TimeSpan?)) 39     { 40       key = AddSysCustomKey(key); 41       string json = ConvertJson(obj); 42       return Do(db => db.StringSet(key, json, expiry)); 43     } 44  45     /// <summary> 46     /// 获取单个key的值 47     /// </summary> 48     /// <param name="key">Redis Key</param> 49     /// <returns></returns> 50     public string StringGet(string key) 51     { 52       key = AddSysCustomKey(key); 53       return Do(db => db.StringGet(key)); 54     } 55  56     /// <summary> 57     /// 获取多个Key 58     /// </summary> 59     /// <param name="listKey">Redis Key集合</param> 60     /// <returns></returns> 61     public RedisValue[] StringGet(List<string> listKey) 62     { 63       List<string> newKeys = listKey.Select(AddSysCustomKey).ToList(); 64       return Do(db => db.StringGet(ConvertRedisKeys(newKeys))); 65     } 66  67     /// <summary> 68     /// 获取一个key的对象 69     /// </summary> 70     /// <typeparam name="T"></typeparam> 71     /// <param name="key"></param> 72     /// <returns></returns> 73     public T StringGet<T>(string key) 74     { 75       key = AddSysCustomKey(key); 76       return Do(db => ConvertObj<T>(db.StringGet(key))); 77     } 78  79     /// <summary> 80     /// 为数字增长val 81     /// </summary> 82     /// <param name="key"></param> 83     /// <param name="val">可以为负</param> 84     /// <returns>增长后的值</returns> 85     public double StringIncrement(string key, double val = 1) 86     { 87       key = AddSysCustomKey(key); 88       return Do(db => db.StringIncrement(key, val)); 89     } 90  91     /// <summary> 92     /// 为数字减少val 93     /// </summary> 94     /// <param name="key"></param> 95     /// <param name="val">可以为负</param> 96     /// <returns>减少后的值</returns> 97     public double StringDecrement(string key, double val = 1) 98     { 99       key = AddSysCustomKey(key);100       return Do(db => db.StringDecrement(key, val));101     }102 103     #endregion 同步方法104 105     #region 异步方法106 107     /// <summary>108     /// 保存单个key value109     /// </summary>110     /// <param name="key">Redis Key</param>111     /// <param name="value">保存的值</param>112     /// <param name="expiry">过期时间</param>113     /// <returns></returns>114     public async Task<bool> StringSetAsync(string key, string value, TimeSpan? expiry = default(TimeSpan?))115     {116       key = AddSysCustomKey(key);117       return await Do(db => db.StringSetAsync(key, value, expiry));118     }119 120     /// <summary>121     /// 保存多个key value122     /// </summary>123     /// <param name="keyValues">键值对</param>124     /// <returns></returns>125     public async Task<bool> StringSetAsync(List<KeyValuePair<RedisKey, RedisValue>> keyValues)126     {127       List<KeyValuePair<RedisKey, RedisValue>> newkeyValues =128         keyValues.Select(p => new KeyValuePair<RedisKey, RedisValue>(AddSysCustomKey(p.Key), p.Value)).ToList();129       return await Do(db => db.StringSetAsync(newkeyValues.ToArray()));130     }131 132     /// <summary>133     /// 保存一个对象134     /// </summary>135     /// <typeparam name="T"></typeparam>136     /// <param name="key"></param>137     /// <param name="obj"></param>138     /// <param name="expiry"></param>139     /// <returns></returns>140     public async Task<bool> StringSetAsync<T>(string key, T obj, TimeSpan? expiry = default(TimeSpan?))141     {142       key = AddSysCustomKey(key);143       string json = ConvertJson(obj);144       return await Do(db => db.StringSetAsync(key, json, expiry));145     }146 147     /// <summary>148     /// 获取单个key的值149     /// </summary>150     /// <param name="key">Redis Key</param>151     /// <returns></returns>152     public async Task<string> StringGetAsync(string key)153     {154       key = AddSysCustomKey(key);155       return await Do(db => db.StringGetAsync(key));156     }157 158     /// <summary>159     /// 获取多个Key160     /// </summary>161     /// <param name="listKey">Redis Key集合</param>162     /// <returns></returns>163     public async Task<RedisValue[]> StringGetAsync(List<string> listKey)164     {165       List<string> newKeys = listKey.Select(AddSysCustomKey).ToList();166       return await Do(db => db.StringGetAsync(ConvertRedisKeys(newKeys)));167     }168 169     /// <summary>170     /// 获取一个key的对象171     /// </summary>172     /// <typeparam name="T"></typeparam>173     /// <param name="key"></param>174     /// <returns></returns>175     public async Task<T> StringGetAsync<T>(string key)176     {177       key = AddSysCustomKey(key);178       string result = await Do(db => db.StringGetAsync(key));179       return ConvertObj<T>(result);180     }181 182     /// <summary>183     /// 为数字增长val184     /// </summary>185     /// <param name="key"></param>186     /// <param name="val">可以为负</param>187     /// <returns>增长后的值</returns>188     public async Task<double> StringIncrementAsync(string key, double val = 1)189     {190       key = AddSysCustomKey(key);191       return await Do(db => db.StringIncrementAsync(key, val));192     }193 194     /// <summary>195     /// 为数字减少val196     /// </summary>197     /// <param name="key"></param>198     /// <param name="val">可以为负</param>199     /// <returns>减少后的值</returns>200     public async Task<double> StringDecrementAsync(string key, double val = 1)201     {202       key = AddSysCustomKey(key);203       return await Do(db => db.StringDecrementAsync(key, val));204     }205 206     #endregion 异步方法207 208     #endregion String

 

  这里说一下,StackExchange.Redis 中对对象的存储是不自带序列化和反序列化的方法,所以在ConvertJson和ConvertObj里面我是使用了JsonConvert来操作,如果需要换成其他的序列化和序列化,直接修改这两个方面就好了,另外,StackExchange.Redis 相对于ServiceStack.Redis 来说提供了异步的方法,所以这里也同样封装了异步和同步的方法。

  Hash类型的封装

 1 #region Hash 2  3     #region 同步方法 4  5     /// <summary> 6     /// 判断某个数据是否已经被缓存 7     /// </summary> 8     /// <param name="key"></param> 9     /// <param name="dataKey"></param> 10     /// <returns></returns> 11     public bool HashExists(string key, string dataKey) 12     { 13       key = AddSysCustomKey(key); 14       return Do(db => db.HashExists(key, dataKey)); 15     } 16  17     /// <summary> 18     /// 存储数据到hash表 19     /// </summary> 20     /// <typeparam name="T"></typeparam> 21     /// <param name="key"></param> 22     /// <param name="dataKey"></param> 23     /// <param name="t"></param> 24     /// <returns></returns> 25     public bool HashSet<T>(string key, string dataKey, T t) 26     { 27       key = AddSysCustomKey(key); 28       return Do(db => 29       { 30         string json = ConvertJson(t); 31         return db.HashSet(key, dataKey, json); 32       }); 33     } 34  35     /// <summary> 36     /// 移除hash中的某值 37     /// </summary> 38     /// <param name="key"></param> 39     /// <param name="dataKey"></param> 40     /// <returns></returns> 41     public bool HashDelete(string key, string dataKey) 42     { 43       key = AddSysCustomKey(key); 44       return Do(db => db.HashDelete(key, dataKey)); 45     } 46  47     /// <summary> 48     /// 移除hash中的多个值 49     /// </summary> 50     /// <param name="key"></param> 51     /// <param name="dataKeys"></param> 52     /// <returns></returns> 53     public long HashDelete(string key, List<RedisValue> dataKeys) 54     { 55       key = AddSysCustomKey(key); 56       //List<RedisValue> dataKeys1 = new List<RedisValue>() {"1","2"}; 57       return Do(db => db.HashDelete(key, dataKeys.ToArray())); 58     } 59  60     /// <summary> 61     /// 从hash表获取数据 62     /// </summary> 63     /// <typeparam name="T"></typeparam> 64     /// <param name="key"></param> 65     /// <param name="dataKey"></param> 66     /// <returns></returns> 67     public T HashGet<T>(string key, string dataKey) 68     { 69       key = AddSysCustomKey(key); 70       return Do(db => 71       { 72         string value = db.HashGet(key, dataKey); 73         return ConvertObj<T>(value); 74       }); 75     } 76  77     /// <summary> 78     /// 为数字增长val 79     /// </summary> 80     /// <param name="key"></param> 81     /// <param name="dataKey"></param> 82     /// <param name="val">可以为负</param> 83     /// <returns>增长后的值</returns> 84     public double HashIncrement(string key, string dataKey, double val = 1) 85     { 86       key = AddSysCustomKey(key); 87       return Do(db => db.HashIncrement(key, dataKey, val)); 88     } 89  90     /// <summary> 91     /// 为数字减少val 92     /// </summary> 93     /// <param name="key"></param> 94     /// <param name="dataKey"></param> 95     /// <param name="val">可以为负</param> 96     /// <returns>减少后的值</returns> 97     public double HashDecrement(string key, string dataKey, double val = 1) 98     { 99       key = AddSysCustomKey(key);100       return Do(db => db.HashDecrement(key, dataKey, val));101     }102 103     /// <summary>104     /// 获取hashkey所有Redis key105     /// </summary>106     /// <typeparam name="T"></typeparam>107     /// <param name="key"></param>108     /// <returns></returns>109     public List<T> HashKeys<T>(string key)110     {111       key = AddSysCustomKey(key);112       return Do(db =>113       {114         RedisValue[] values = db.HashKeys(key);115         return ConvetList<T>(values);116       });117     }118 119     #endregion 同步方法120 121     #region 异步方法122 123     /// <summary>124     /// 判断某个数据是否已经被缓存125     /// </summary>126     /// <param name="key"></param>127     /// <param name="dataKey"></param>128     /// <returns></returns>129     public async Task<bool> HashExistsAsync(string key, string dataKey)130     {131       key = AddSysCustomKey(key);132       return await Do(db => db.HashExistsAsync(key, dataKey));133     }134 135     /// <summary>136     /// 存储数据到hash表137     /// </summary>138     /// <typeparam name="T"></typeparam>139     /// <param name="key"></param>140     /// <param name="dataKey"></param>141     /// <param name="t"></param>142     /// <returns></returns>143     public async Task<bool> HashSetAsync<T>(string key, string dataKey, T t)144     {145       key = AddSysCustomKey(key);146       return await Do(db =>147       {148         string json = ConvertJson(t);149         return db.HashSetAsync(key, dataKey, json);150       });151     }152 153     /// <summary>154     /// 移除hash中的某值155     /// </summary>156     /// <param name="key"></param>157     /// <param name="dataKey"></param>158     /// <returns></returns>159     public async Task<bool> HashDeleteAsync(string key, string dataKey)160     {161       key = AddSysCustomKey(key);162       return await Do(db => db.HashDeleteAsync(key, dataKey));163     }164 165     /// <summary>166     /// 移除hash中的多个值167     /// </summary>168     /// <param name="key"></param>169     /// <param name="dataKeys"></param>170     /// <returns></returns>171     public async Task<long> HashDeleteAsync(string key, List<RedisValue> dataKeys)172     {173       key = AddSysCustomKey(key);174       //List<RedisValue> dataKeys1 = new List<RedisValue>() {"1","2"};175       return await Do(db => db.HashDeleteAsync(key, dataKeys.ToArray()));176     }177 178     /// <summary>179     /// 从hash表获取数据180     /// </summary>181     /// <typeparam name="T"></typeparam>182     /// <param name="key"></param>183     /// <param name="dataKey"></param>184     /// <returns></returns>185     public async Task<T> HashGeAsync<T>(string key, string dataKey)186     {187       key = AddSysCustomKey(key);188       string value = await Do(db => db.HashGetAsync(key, dataKey));189       return ConvertObj<T>(value);190     }191 192     /// <summary>193     /// 为数字增长val194     /// </summary>195     /// <param name="key"></param>196     /// <param name="dataKey"></param>197     /// <param name="val">可以为负</param>198     /// <returns>增长后的值</returns>199     public async Task<double> HashIncrementAsync(string key, string dataKey, double val = 1)200     {201       key = AddSysCustomKey(key);202       return await Do(db => db.HashIncrementAsync(key, dataKey, val));203     }204 205     /// <summary>206     /// 为数字减少val207     /// </summary>208     /// <param name="key"></param>209     /// <param name="dataKey"></param>210     /// <param name="val">可以为负</param>211     /// <returns>减少后的值</returns>212     public async Task<double> HashDecrementAsync(string key, string dataKey, double val = 1)213     {214       key = AddSysCustomKey(key);215       return await Do(db => db.HashDecrementAsync(key, dataKey, val));216     }217 218     /// <summary>219     /// 获取hashkey所有Redis key220     /// </summary>221     /// <typeparam name="T"></typeparam>222     /// <param name="key"></param>223     /// <returns></returns>224     public async Task<List<T>> HashKeysAsync<T>(string key)225     {226       key = AddSysCustomKey(key);227       RedisValue[] values = await Do(db => db.HashKeysAsync(key));228       return ConvetList<T>(values);229     }230 231     #endregion 异步方法232 233     #endregion Hash

  List类型的封装

 1  #region List 2  3     #region 同步方法 4  5     /// <summary> 6     /// 移除指定ListId的内部List的值 7     /// </summary> 8     /// <param name="key"></param> 9     /// <param name="value"></param> 10     public void ListRemove<T>(string key, T value) 11     { 12       key = AddSysCustomKey(key); 13       Do(db => db.ListRemove(key, ConvertJson(value))); 14     } 15  16     /// <summary> 17     /// 获取指定key的List 18     /// </summary> 19     /// <param name="key"></param> 20     /// <returns></returns> 21     public List<T> ListRange<T>(string key) 22     { 23       key = AddSysCustomKey(key); 24       return Do(redis => 25       { 26         var values = redis.ListRange(key); 27         return ConvetList<T>(values); 28       }); 29     } 30  31     /// <summary> 32     /// 入队 33     /// </summary> 34     /// <param name="key"></param> 35     /// <param name="value"></param> 36     public void ListRightPush<T>(string key, T value) 37     { 38       key = AddSysCustomKey(key); 39       Do(db => db.ListRightPush(key, ConvertJson(value))); 40     } 41  42     /// <summary> 43     /// 出队 44     /// </summary> 45     /// <typeparam name="T"></typeparam> 46     /// <param name="key"></param> 47     /// <returns></returns> 48     public T ListRightPop<T>(string key) 49     { 50       key = AddSysCustomKey(key); 51       return Do(db => 52        { 53         var value = db.ListRightPop(key); 54         return ConvertObj<T>(value); 55        }); 56     } 57  58     /// <summary> 59     /// 入栈 60     /// </summary> 61     /// <typeparam name="T"></typeparam> 62     /// <param name="key"></param> 63     /// <param name="value"></param> 64     public void ListLeftPush<T>(string key, T value) 65     { 66       key = AddSysCustomKey(key); 67       Do(db => db.ListLeftPush(key, ConvertJson(value))); 68     } 69  70     /// <summary> 71     /// 出栈 72     /// </summary> 73     /// <typeparam name="T"></typeparam> 74     /// <param name="key"></param> 75     /// <returns></returns> 76     public T ListLeftPop<T>(string key) 77     { 78       key = AddSysCustomKey(key); 79       return Do(db => 80       { 81         var value = db.ListLeftPop(key); 82         return ConvertObj<T>(value); 83       }); 84     } 85  86     /// <summary> 87     /// 获取集合中的数量 88     /// </summary> 89     /// <param name="key"></param> 90     /// <returns></returns> 91     public long ListLength(string key) 92     { 93       key = AddSysCustomKey(key); 94       return Do(redis => redis.ListLength(key)); 95     } 96  97     #endregion 同步方法 98  99     #region 异步方法100 101     /// <summary>102     /// 移除指定ListId的内部List的值103     /// </summary>104     /// <param name="key"></param>105     /// <param name="value"></param>106     public async Task<long> ListRemoveAsync<T>(string key, T value)107     {108       key = AddSysCustomKey(key);109       return await Do(db => db.ListRemoveAsync(key, ConvertJson(value)));110     }111 112     /// <summary>113     /// 获取指定key的List114     /// </summary>115     /// <param name="key"></param>116     /// <returns></returns>117     public async Task<List<T>> ListRangeAsync<T>(string key)118     {119       key = AddSysCustomKey(key);120       var values = await Do(redis => redis.ListRangeAsync(key));121       return ConvetList<T>(values);122     }123 124     /// <summary>125     /// 入队126     /// </summary>127     /// <param name="key"></param>128     /// <param name="value"></param>129     public async Task<long> ListRightPushAsync<T>(string key, T value)130     {131       key = AddSysCustomKey(key);132       return await Do(db => db.ListRightPushAsync(key, ConvertJson(value)));133     }134 135     /// <summary>136     /// 出队137     /// </summary>138     /// <typeparam name="T"></typeparam>139     /// <param name="key"></param>140     /// <returns></returns>141     public async Task<T> ListRightPopAsync<T>(string key)142     {143       key = AddSysCustomKey(key);144       var value = await Do(db => db.ListRightPopAsync(key));145       return ConvertObj<T>(value);146     }147 148     /// <summary>149     /// 入栈150     /// </summary>151     /// <typeparam name="T"></typeparam>152     /// <param name="key"></param>153     /// <param name="value"></param>154     public async Task<long> ListLeftPushAsync<T>(string key, T value)155     {156       key = AddSysCustomKey(key);157       return await Do(db => db.ListLeftPushAsync(key, ConvertJson(value)));158     }159 160     /// <summary>161     /// 出栈162     /// </summary>163     /// <typeparam name="T"></typeparam>164     /// <param name="key"></param>165     /// <returns></returns>166     public async Task<T> ListLeftPopAsync<T>(string key)167     {168       key = AddSysCustomKey(key);169       var value = await Do(db => db.ListLeftPopAsync(key));170       return ConvertObj<T>(value);171     }172 173     /// <summary>174     /// 获取集合中的数量175     /// </summary>176     /// <param name="key"></param>177     /// <returns></returns>178     public async Task<long> ListLengthAsync(string key)179     {180       key = AddSysCustomKey(key);181       return await Do(redis => redis.ListLengthAsync(key));182     }183 184     #endregion 异步方法185 186     #endregion List

  SortedSet 类型的封装

 1     #region SortedSet 有序集合 2  3     #region 同步方法 4  5     /// <summary> 6     /// 添加 7     /// </summary> 8     /// <param name="key"></param> 9     /// <param name="value"></param> 10     /// <param name="score"></param> 11     public bool SortedSetAdd<T>(string key, T value, double score) 12     { 13       key = AddSysCustomKey(key); 14       return Do(redis => redis.SortedSetAdd(key, ConvertJson<T>(value), score)); 15     } 16  17     /// <summary> 18     /// 删除 19     /// </summary> 20     /// <param name="key"></param> 21     /// <param name="value"></param> 22     public bool SortedSetRemove<T>(string key, T value) 23     { 24       key = AddSysCustomKey(key); 25       return Do(redis => redis.SortedSetRemove(key, ConvertJson(value))); 26     } 27  28     /// <summary> 29     /// 获取全部 30     /// </summary> 31     /// <param name="key"></param> 32     /// <returns></returns> 33     public List<T> SortedSetRangeByRank<T>(string key) 34     { 35       key = AddSysCustomKey(key); 36       return Do(redis => 37       { 38         var values = redis.SortedSetRangeByRank(key); 39         return ConvetList<T>(values); 40       }); 41     } 42  43     /// <summary> 44     /// 获取集合中的数量 45     /// </summary> 46     /// <param name="key"></param> 47     /// <returns></returns> 48     public long SortedSetLength(string key) 49     { 50       key = AddSysCustomKey(key); 51       return Do(redis => redis.SortedSetLength(key)); 52     } 53  54     #endregion 同步方法 55  56     #region 异步方法 57  58     /// <summary> 59     /// 添加 60     /// </summary> 61     /// <param name="key"></param> 62     /// <param name="value"></param> 63     /// <param name="score"></param> 64     public async Task<bool> SortedSetAddAsync<T>(string key, T value, double score) 65     { 66       key = AddSysCustomKey(key); 67       return await Do(redis => redis.SortedSetAddAsync(key, ConvertJson<T>(value), score)); 68     } 69  70     /// <summary> 71     /// 删除 72     /// </summary> 73     /// <param name="key"></param> 74     /// <param name="value"></param> 75     public async Task<bool> SortedSetRemoveAsync<T>(string key, T value) 76     { 77       key = AddSysCustomKey(key); 78       return await Do(redis => redis.SortedSetRemoveAsync(key, ConvertJson(value))); 79     } 80  81     /// <summary> 82     /// 获取全部 83     /// </summary> 84     /// <param name="key"></param> 85     /// <returns></returns> 86     public async Task<List<T>> SortedSetRangeByRankAsync<T>(string key) 87     { 88       key = AddSysCustomKey(key); 89       var values = await Do(redis => redis.SortedSetRangeByRankAsync(key)); 90       return ConvetList<T>(values); 91     } 92  93     /// <summary> 94     /// 获取集合中的数量 95     /// </summary> 96     /// <param name="key"></param> 97     /// <returns></returns> 98     public async Task<long> SortedSetLengthAsync(string key) 99     {100       key = AddSysCustomKey(key);101       return await Do(redis => redis.SortedSetLengthAsync(key));102     }103 104     #endregion 异步方法105 106     #endregion SortedSet 有序集合

  key的管理

 1  #region key 2  3     /// <summary> 4     /// 删除单个key 5     /// </summary> 6     /// <param name="key">redis key</param> 7     /// <returns>是否删除成功</returns> 8     public bool KeyDelete(string key) 9     {10       key = AddSysCustomKey(key);11       return Do(db => db.KeyDelete(key));12     }13 14     /// <summary>15     /// 删除多个key16     /// </summary>17     /// <param name="keys">rediskey</param>18     /// <returns>成功删除的个数</returns>19     public long KeyDelete(List<string> keys)20     {21       List<string> newKeys = keys.Select(AddSysCustomKey).ToList();22       return Do(db => db.KeyDelete(ConvertRedisKeys(newKeys)));23     }24 25     /// <summary>26     /// 判断key是否存储27     /// </summary>28     /// <param name="key">redis key</param>29     /// <returns></returns>30     public bool KeyExists(string key)31     {32       key = AddSysCustomKey(key);33       return Do(db => db.KeyExists(key));34     }35 36     /// <summary>37     /// 重新命名key38     /// </summary>39     /// <param name="key">就的redis key</param>40     /// <param name="newKey">新的redis key</param>41     /// <returns></returns>42     public bool KeyRename(string key, string newKey)43     {44       key = AddSysCustomKey(key);45       return Do(db => db.KeyRename(key, newKey));46     }47 48     /// <summary>49     /// 设置Key的时间50     /// </summary>51     /// <param name="key">redis key</param>52     /// <param name="expiry"></param>53     /// <returns></returns>54     public bool KeyExpire(string key, TimeSpan? expiry = default(TimeSpan?))55     {56       key = AddSysCustomKey(key);57       return Do(db => db.KeyExpire(key, expiry));58     }59 60     #endregion key

  发布和订阅

 1 #region 发布订阅 2  3     /// <summary> 4     /// Redis发布订阅 订阅 5     /// </summary> 6     /// <param name="subChannel"></param> 7     /// <param name="handler"></param> 8     public void Subscribe(string subChannel, Action<RedisChannel, RedisValue> handler = null) 9     {10       ISubscriber sub = _conn.GetSubscriber();11       sub.Subscribe(subChannel, (channel, message) =>12       {13         if (handler == null)14         {15           Console.WriteLine(subChannel + " 订阅收到消息:" + message);16         }17         else18         {19           handler(channel, message);20         }21       });22     }23 24     /// <summary>25     /// Redis发布订阅 发布26     /// </summary>27     /// <typeparam name="T"></typeparam>28     /// <param name="channel"></param>29     /// <param name="msg"></param>30     /// <returns></returns>31     public long Publish<T>(string channel, T msg)32     {33       ISubscriber sub = _conn.GetSubscriber();34       return sub.Publish(channel, ConvertJson(msg));35     }36 37     /// <summary>38     /// Redis发布订阅 取消订阅39     /// </summary>40     /// <param name="channel"></param>41     public void Unsubscribe(string channel)42     {43       ISubscriber sub = _conn.GetSubscriber();44       sub.Unsubscribe(channel);45     }46 47     /// <summary>48     /// Redis发布订阅 取消全部订阅49     /// </summary>50     public void UnsubscribeAll()51     {52       ISubscriber sub = _conn.GetSubscriber();53       sub.UnsubscribeAll();54     }55 56     #endregion 发布订阅

  其他

 1 #region 其他 2  3     public ITransaction CreateTransaction() 4     { 5       return GetDatabase().CreateTransaction(); 6     } 7  8     public IDatabase GetDatabase() 9     {10       return _conn.GetDatabase(DbNum);11     }12 13     public IServer GetServer(string hostAndPort)14     {15       return _conn.GetServer(hostAndPort);16     }17 18     /// <summary>19     /// 设置前缀20     /// </summary>21     /// <param name="customKey"></param>22     public void SetSysCustomKey(string customKey)23     {24       CustomKey = customKey;25     }26 27     #endregion 其他

  以上就是对StackExchange.Redis基本操作的通用封装,提供给大家学习参考,如果有哪里写错的,也希望能一起交流。

  问题:

  StackExchange.Redis没有提供Redis分布式锁的操作么?ServiceStack.Redis 提供了AcquireLock 的方法来操作,StackExchange.Redis 源码中只找到了LockTake的方法,并没有找到其他的方法了,如果有人使用过,还希望能提供下。

  最后,附上源码地址:https://github.com/qq1206676756/RedisHelp