Redis 小白指南(一)

栏目: 数据库 · 发布时间: 6年前

内容简介:Redis 小白指南(一)

Redis 小白指南(一)

目录

  • 简介
  • 安装
  • 入门指令
  • GUI 工具
  • C# 驱动介绍

简介

ANSI C 编写,开源,基于内存,可持久化,一个键值对的数据库,用法简单。

支持的类型:字符串、散列、列表、集合和有序集合。

功能丰富:可以为每个键设置设置生存时间,到期自动删除,也就是说可以作为缓存系统进行使用。相对于 Memcached:Redis 单线程模型,Memcached 支持多线程,Redis 支持的功能更多。Redis 可以限定数据共用的最大内存空间,在数据达到空间限制后按一定规则自动淘汰不需要的键。

Redis 小白指南(一)

安装

它的约定次版本号(即第一个小数点后的数字)为偶数的版本是稳定版(如 v2.8,v3.0)。

redis-windows-3.0:下载地址

Redis 小白指南(一)

文件的作用和意义:

Redis 小白指南(一)

入门指令

TODO

GUI 工具

Redis Client:一个基于Java SWT和Jedis编写的 redis 客户端GUI工具。可从 https://github.com/caoxinyu/RedisClient 下载。

Redis 小白指南(一)

从图可知,redis 包含了 16 个数据库,从 0 开始,每个数据库以编号进行命名,并且,他们的名字无法修改。

因为该程序打包后的压缩包 >10 M,无法上传到 cnblogs,如有需要的童鞋请加群在群文件中下载压缩包。

Redis 小白指南(一)

C# 驱动

之前在 http://www.cnblogs.com/liqingwen/p/6672452.html 曾经发布了一篇进行 StackExchange.Redis 简单封装的 RedisHelper,你可以从 https://github.com/liqingwen2015/Wen.Helpers 查看更新后的 Helper 代码(或者展开下面的代码)。


   1 #region
   2 
   3 using System;
   4 using System.Collections.Generic;
   5 using System.Configuration;
   6 using System.IO;
   7 using System.Linq;
   8 using System.Runtime.Serialization.Formatters.Binary;
   9 using System.Threading.Tasks;
  10 using StackExchange.Redis;
  11 
  12 #endregion
  13 
  14 namespace Wen.Helpers.Common.Redis
  15 {
  16     /// <summary>
  17     /// Redis 助手
  18     /// </summary>
  19     public class RedisHelper
  20     {
  21         /// <summary>
  22         /// 获取 Redis 连接对象
  23         /// </summary>
  24         /// <returns></returns>
  25         public IConnectionMultiplexer GetConnectionRedisMultiplexer()
  26         {
  27             if (_connMultiplexer == null || !_connMultiplexer.IsConnected)
  28                 lock (Locker)
  29                 {
  30                     if (_connMultiplexer == null || !_connMultiplexer.IsConnected)
  31                         _connMultiplexer = ConnectionMultiplexer.Connect(ConnectionString);
  32                 }
  33 
  34             return _connMultiplexer;
  35         }
  36 
  37         #region 其它
  38 
  39         public ITransaction GetTransaction()
  40         {
  41             return _db.CreateTransaction();
  42         }
  43 
  44         #endregion 其它
  45 
  46         #region private field
  47 
  48         /// <summary>
  49         /// 连接字符串
  50         /// </summary>
  51         private static readonly string ConnectionString;
  52 
  53         /// <summary>
  54         /// redis 连接对象
  55         /// </summary>
  56         private static IConnectionMultiplexer _connMultiplexer;
  57 
  58         /// <summary>
  59         /// 默认的 Key 值(用来当作 RedisKey 的前缀)
  60         /// </summary>
  61         private static readonly string DefaultKey;
  62 
  63         /// <summary>
  64         /// 锁
  65         /// </summary>
  66         private static readonly object Locker = new object();
  67 
  68         /// <summary>
  69         /// 数据库
  70         /// </summary>
  71         private readonly IDatabase _db;
  72 
  73         #endregion private field
  74 
  75         #region 构造函数
  76 
  77         static RedisHelper()
  78         {
  79             ConnectionString = ConfigurationManager.ConnectionStrings["RedisConnectionString"].ConnectionString;
  80             _connMultiplexer = ConnectionMultiplexer.Connect(ConnectionString);
  81             DefaultKey = ConfigurationManager.AppSettings["Redis.DefaultKey"];
  82             AddRegisterEvent();
  83         }
  84 
  85         public RedisHelper(int db = 0)
  86         {
  87             _db = _connMultiplexer.GetDatabase(db);
  88         }
  89 
  90         #endregion 构造函数
  91 
  92         #region String 操作
  93 
  94         /// <summary>
  95         /// 设置 key 并保存字符串(如果 key 已存在,则覆盖值)
  96         /// </summary>
  97         /// <param name="key"></param>
  98         /// <param name="value"></param>
  99         /// <param name="expiry"></param>
 100         /// <returns></returns>
 101         public bool StringSet(string key, string value, TimeSpan? expiry = null)
 102         {
 103             key = AddKeyPrefix(key);
 104             return _db.StringSet(key, value, expiry);
 105         }
 106 
 107         /// <summary>
 108         /// 保存多个 Key-value
 109         /// </summary>
 110         /// <param name="keyValuePairs"></param>
 111         /// <returns></returns>
 112         public bool StringSet(IEnumerable<KeyValuePair<string, string>> keyValuePairs)
 113         {
 114             var pairs = keyValuePairs.Select(x => new KeyValuePair<RedisKey, RedisValue>(AddKeyPrefix(x.Key), x.Value));
 115             return _db.StringSet(pairs.ToArray());
 116         }
 117 
 118         /// <summary>
 119         /// 获取字符串
 120         /// </summary>
 121         /// <param name="redisKey"></param>
 122         /// <param name="expiry"></param>
 123         /// <returns></returns>
 124         public string StringGet(string redisKey)
 125         {
 126             redisKey = AddKeyPrefix(redisKey);
 127             return _db.StringGet(redisKey);
 128         }
 129 
 130         /// <summary>
 131         /// 存储一个对象(该对象会被序列化保存)
 132         /// </summary>
 133         /// <param name="key"></param>
 134         /// <param name="value"></param>
 135         /// <param name="expiry"></param>
 136         /// <returns></returns>
 137         public bool StringSet<T>(string key, T value, TimeSpan? expiry = null)
 138         {
 139             key = AddKeyPrefix(key);
 140             var json = Serialize(value);
 141 
 142             return _db.StringSet(key, json, expiry);
 143         }
 144 
 145         /// <summary>
 146         /// 获取一个对象(会进行反序列化)
 147         /// </summary>
 148         /// <param name="key"></param>
 149         /// <param name="expiry"></param>
 150         /// <returns></returns>
 151         public T StringGet<T>(string key, TimeSpan? expiry = null)
 152         {
 153             key = AddKeyPrefix(key);
 154             return Deserialize<T>(_db.StringGet(key));
 155         }
 156 
 157         /// <summary>
 158         /// 在指定 key 处实现增量的递增,如果该键不存在,则在执行前将其设置为 0
 159         /// </summary>
 160         /// <param name="key"></param>
 161         /// <param name="value"></param>
 162         /// <returns></returns>
 163         public double StringIncrement(string key, double value = 1)
 164         {
 165             key = AddKeyPrefix(key);
 166             return _db.StringIncrement(key, value);
 167         }
 168 
 169         /// <summary>
 170         /// 在指定 key 处实现增量的递减,如果该键不存在,则在执行前将其设置为 0
 171         /// </summary>
 172         /// <param name="key"></param>
 173         /// <param name="value"></param>
 174         /// <returns></returns>
 175         public double StringDecrement(string key, double value = 1)
 176         {
 177             key = AddKeyPrefix(key);
 178             return _db.StringDecrement(key, value);
 179         }
 180 
 181         #region async
 182 
 183         /// <summary>
 184         /// 保存一个字符串值
 185         /// </summary>
 186         /// <param name="key"></param>
 187         /// <param name="value"></param>
 188         /// <param name="expiry"></param>
 189         /// <returns></returns>
 190         public async Task<bool> StringSetAsync(string key, string value, TimeSpan? expiry = null)
 191         {
 192             key = AddKeyPrefix(key);
 193             return await _db.StringSetAsync(key, value, expiry);
 194         }
 195 
 196         /// <summary>
 197         /// 保存一组字符串值
 198         /// </summary>
 199         /// <param name="keyValuePairs"></param>
 200         /// <returns></returns>
 201         public async Task<bool> StringSetAsync(IEnumerable<KeyValuePair<string, string>> keyValuePairs)
 202         {
 203             var pairs = keyValuePairs.Select(x => new KeyValuePair<RedisKey, RedisValue>(AddKeyPrefix(x.Key), x.Value));
 204             return await _db.StringSetAsync(pairs.ToArray());
 205         }
 206 
 207         /// <summary>
 208         /// 获取单个值
 209         /// </summary>
 210         /// <param name="key"></param>
 211         /// <param name="value"></param>
 212         /// <param name="expiry"></param>
 213         /// <returns></returns>
 214         public async Task<string> StringGetAsync(string key, string value, TimeSpan? expiry = null)
 215         {
 216             key = AddKeyPrefix(key);
 217             return await _db.StringGetAsync(key);
 218         }
 219 
 220         /// <summary>
 221         /// 存储一个对象(该对象会被序列化保存)
 222         /// </summary>
 223         /// <param name="key"></param>
 224         /// <param name="value"></param>
 225         /// <param name="expiry"></param>
 226         /// <returns></returns>
 227         public async Task<bool> StringSetAsync<T>(string key, T value, TimeSpan? expiry = null)
 228         {
 229             key = AddKeyPrefix(key);
 230             var json = Serialize(value);
 231             return await _db.StringSetAsync(key, json, expiry);
 232         }
 233 
 234         /// <summary>
 235         /// 获取一个对象(会进行反序列化)
 236         /// </summary>
 237         /// <param name="key"></param>
 238         /// <param name="expiry"></param>
 239         /// <returns></returns>
 240         public async Task<T> StringGetAsync<T>(string key, TimeSpan? expiry = null)
 241         {
 242             key = AddKeyPrefix(key);
 243             return Deserialize<T>(await _db.StringGetAsync(key));
 244         }
 245 
 246         /// <summary>
 247         /// 在指定 key 处实现增量的递增,如果该键不存在,则在执行前将其设置为 0
 248         /// </summary>
 249         /// <param name="key"></param>
 250         /// <param name="value"></param>
 251         /// <returns></returns>
 252         public async Task<double> StringIncrementAsync(string key, double value = 1)
 253         {
 254             key = AddKeyPrefix(key);
 255             return await _db.StringIncrementAsync(key, value);
 256         }
 257 
 258         /// <summary>
 259         /// 在指定 key 处实现增量的递减,如果该键不存在,则在执行前将其设置为 0
 260         /// </summary>
 261         /// <param name="key"></param>
 262         /// <param name="value"></param>
 263         /// <returns></returns>
 264         public async Task<double> StringDecrementAsync(string key, double value = 1)
 265         {
 266             key = AddKeyPrefix(key);
 267             return await _db.StringDecrementAsync(key, value);
 268         }
 269 
 270         #endregion async
 271 
 272         #endregion String 操作
 273 
 274         #region Hash 操作
 275 
 276         /// <summary>
 277         /// 判断该字段是否存在 hash 中
 278         /// </summary>
 279         /// <param name="key"></param>
 280         /// <param name="hashField"></param>
 281         /// <returns></returns>
 282         public bool HashExists(string key, string hashField)
 283         {
 284             key = AddKeyPrefix(key);
 285             return _db.HashExists(key, hashField);
 286         }
 287 
 288         /// <summary>
 289         /// 从 hash 中移除指定字段
 290         /// </summary>
 291         /// <param name="key"></param>
 292         /// <param name="hashField"></param>
 293         /// <returns></returns>
 294         public bool HashDelete(string key, string hashField)
 295         {
 296             key = AddKeyPrefix(key);
 297             return _db.HashDelete(key, hashField);
 298         }
 299 
 300         /// <summary>
 301         /// 从 hash 中移除指定字段
 302         /// </summary>
 303         /// <param name="key"></param>
 304         /// <param name="hashFields"></param>
 305         /// <returns></returns>
 306         public long HashDelete(string key, IEnumerable<string> hashFields)
 307         {
 308             key = AddKeyPrefix(key);
 309             var fields = hashFields.Select(x => (RedisValue) x);
 310 
 311             return _db.HashDelete(key, fields.ToArray());
 312         }
 313 
 314         /// <summary>
 315         /// 在 hash 设定值
 316         /// </summary>
 317         /// <param name="key"></param>
 318         /// <param name="hashField"></param>
 319         /// <param name="value"></param>
 320         /// <returns></returns>
 321         public bool HashSet(string key, string hashField, string value)
 322         {
 323             key = AddKeyPrefix(key);
 324             return _db.HashSet(key, hashField, value);
 325         }
 326 
 327         /// <summary>
 328         /// 在 hash 中设定值
 329         /// </summary>
 330         /// <param name="key"></param>
 331         /// <param name="hashFields"></param>
 332         public void HashSet(string key, IEnumerable<KeyValuePair<string, string>> hashFields)
 333         {
 334             key = AddKeyPrefix(key);
 335             var entries = hashFields.Select(x => new HashEntry(x.Key, x.Value));
 336 
 337             _db.HashSet(key, entries.ToArray());
 338         }
 339 
 340         /// <summary>
 341         /// 在 hash 中获取值
 342         /// </summary>
 343         /// <param name="key"></param>
 344         /// <param name="hashField"></param>
 345         /// <returns></returns>
 346         public string HashGet(string key, string hashField)
 347         {
 348             key = AddKeyPrefix(key);
 349             return _db.HashGet(key, hashField);
 350         }
 351 
 352         /// <summary>
 353         /// 在 hash 中获取值
 354         /// </summary>
 355         /// <param name="key"></param>
 356         /// <param name="hashFields"></param>
 357         /// <returns></returns>
 358         public IEnumerable<string> HashGet(string key, IEnumerable<string> hashFields)
 359         {
 360             key = AddKeyPrefix(key);
 361             var fields = hashFields.Select(x => (RedisValue) x);
 362 
 363             return ConvertStrings(_db.HashGet(key, fields.ToArray()));
 364         }
 365 
 366         /// <summary>
 367         /// 从 hash 返回所有的字段值
 368         /// </summary>
 369         /// <param name="key"></param>
 370         /// <returns></returns>
 371         public IEnumerable<string> HashKeys(string key)
 372         {
 373             key = AddKeyPrefix(key);
 374             return ConvertStrings(_db.HashKeys(key));
 375         }
 376 
 377         /// <summary>
 378         /// 返回 hash 中的所有值
 379         /// </summary>
 380         /// <param name="key"></param>
 381         /// <returns></returns>
 382         public IEnumerable<string> HashValues(string key)
 383         {
 384             key = AddKeyPrefix(key);
 385             return ConvertStrings(_db.HashValues(key));
 386         }
 387 
 388         /// <summary>
 389         /// 在 hash 设定值(序列化)
 390         /// </summary>
 391         /// <param name="key"></param>
 392         /// <param name="hashField"></param>
 393         /// <param name="redisValue"></param>
 394         /// <returns></returns>
 395         public bool HashSet<T>(string key, string hashField, T redisValue)
 396         {
 397             key = AddKeyPrefix(key);
 398             var json = Serialize(redisValue);
 399 
 400             return _db.HashSet(key, hashField, json);
 401         }
 402 
 403         /// <summary>
 404         /// 在 hash 中获取值(反序列化)
 405         /// </summary>
 406         /// <param name="key"></param>
 407         /// <param name="hashField"></param>
 408         /// <returns></returns>
 409         public T HashGet<T>(string key, string hashField)
 410         {
 411             key = AddKeyPrefix(key);
 412             return Deserialize<T>(_db.HashGet(key, hashField));
 413         }
 414 
 415         /// <summary>
 416         /// 指定键递增
 417         /// </summary>
 418         /// <param name="key"></param>
 419         /// <param name="hashField"></param>
 420         /// <param name="value"></param>
 421         /// <returns></returns>
 422         public double HashIncrement(string key, string hashField, double value = 1)
 423         {
 424             key = AddKeyPrefix(key);
 425             return _db.HashIncrement(key, hashField, value);
 426         }
 427 
 428         /// <summary>
 429         /// 指定键递减
 430         /// </summary>
 431         /// <param name="key"></param>
 432         /// <param name="hashField"></param>
 433         /// <param name="value"></param>
 434         /// <returns></returns>
 435         public double HashDecrement(string key, string hashField, double value = 1)
 436         {
 437             key = AddKeyPrefix(key);
 438             return _db.HashDecrement(key, hashField, value);
 439         }
 440 
 441         #region async
 442 
 443         /// <summary>
 444         /// 判断该字段是否存在 hash 中
 445         /// </summary>
 446         /// <param name="redisKey"></param>
 447         /// <param name="hashField"></param>
 448         /// <returns></returns>
 449         public async Task<bool> HashExistsAsync(string redisKey, string hashField)
 450         {
 451             redisKey = AddKeyPrefix(redisKey);
 452             return await _db.HashExistsAsync(redisKey, hashField);
 453         }
 454 
 455         /// <summary>
 456         /// 从 hash 中移除指定字段
 457         /// </summary>
 458         /// <param name="redisKey"></param>
 459         /// <param name="hashField"></param>
 460         /// <returns></returns>
 461         public async Task<bool> HashDeleteAsync(string redisKey, string hashField)
 462         {
 463             redisKey = AddKeyPrefix(redisKey);
 464             return await _db.HashDeleteAsync(redisKey, hashField);
 465         }
 466 
 467         /// <summary>
 468         /// 从 hash 中移除指定字段
 469         /// </summary>
 470         /// <param name="redisKey"></param>
 471         /// <param name="hashFields"></param>
 472         /// <returns></returns>
 473         public async Task<long> HashDeleteAsync(string redisKey, IEnumerable<string> hashFields)
 474         {
 475             redisKey = AddKeyPrefix(redisKey);
 476             var fields = hashFields.Select(x => (RedisValue) x);
 477 
 478             return await _db.HashDeleteAsync(redisKey, fields.ToArray());
 479         }
 480 
 481         /// <summary>
 482         /// 在 hash 设定值
 483         /// </summary>
 484         /// <param name="redisKey"></param>
 485         /// <param name="hashField"></param>
 486         /// <param name="value"></param>
 487         /// <returns></returns>
 488         public async Task<bool> HashSetAsync(string redisKey, string hashField, string value)
 489         {
 490             redisKey = AddKeyPrefix(redisKey);
 491             return await _db.HashSetAsync(redisKey, hashField, value);
 492         }
 493 
 494         /// <summary>
 495         /// 在 hash 中设定值
 496         /// </summary>
 497         /// <param name="redisKey"></param>
 498         /// <param name="hashFields"></param>
 499         public async Task HashSetAsync(string redisKey, IEnumerable<KeyValuePair<string, string>> hashFields)
 500         {
 501             redisKey = AddKeyPrefix(redisKey);
 502             var entries = hashFields.Select(x => new HashEntry(AddKeyPrefix(x.Key), x.Value));
 503             await _db.HashSetAsync(redisKey, entries.ToArray());
 504         }
 505 
 506         /// <summary>
 507         /// 在 hash 中获取值
 508         /// </summary>
 509         /// <param name="redisKey"></param>
 510         /// <param name="hashField"></param>
 511         /// <returns></returns>
 512         public async Task<string> HashGetAsync(string redisKey, string hashField)
 513         {
 514             redisKey = AddKeyPrefix(redisKey);
 515             return await _db.HashGetAsync(redisKey, hashField);
 516         }
 517 
 518         /// <summary>
 519         /// 在 hash 中获取值
 520         /// </summary>
 521         /// <param name="redisKey"></param>
 522         /// <param name="hashFields"></param>
 523         /// <param name="value"></param>
 524         /// <returns></returns>
 525         public async Task<IEnumerable<string>> HashGetAsync(string redisKey, IEnumerable<string> hashFields,
 526             string value)
 527         {
 528             redisKey = AddKeyPrefix(redisKey);
 529             var fields = hashFields.Select(x => (RedisValue) x);
 530 
 531             return ConvertStrings(await _db.HashGetAsync(redisKey, fields.ToArray()));
 532         }
 533 
 534         /// <summary>
 535         /// 从 hash 返回所有的字段值
 536         /// </summary>
 537         /// <param name="redisKey"></param>
 538         /// <returns></returns>
 539         public async Task<IEnumerable<string>> HashKeysAsync(string redisKey)
 540         {
 541             redisKey = AddKeyPrefix(redisKey);
 542             return ConvertStrings(await _db.HashKeysAsync(redisKey));
 543         }
 544 
 545         /// <summary>
 546         /// 返回 hash 中的所有值
 547         /// </summary>
 548         /// <param name="redisKey"></param>
 549         /// <returns></returns>
 550         public async Task<IEnumerable<string>> HashValuesAsync(string redisKey)
 551         {
 552             redisKey = AddKeyPrefix(redisKey);
 553             return ConvertStrings(await _db.HashValuesAsync(redisKey));
 554         }
 555 
 556         /// <summary>
 557         /// 在 hash 设定值(序列化)
 558         /// </summary>
 559         /// <param name="redisKey"></param>
 560         /// <param name="hashField"></param>
 561         /// <param name="value"></param>
 562         /// <returns></returns>
 563         public async Task<bool> HashSetAsync<T>(string redisKey, string hashField, T value)
 564         {
 565             redisKey = AddKeyPrefix(redisKey);
 566             var json = Serialize(value);
 567             return await _db.HashSetAsync(redisKey, hashField, json);
 568         }
 569 
 570         /// <summary>
 571         /// 在 hash 中获取值(反序列化)
 572         /// </summary>
 573         /// <param name="redisKey"></param>
 574         /// <param name="hashField"></param>
 575         /// <returns></returns>
 576         public async Task<T> HashGetAsync<T>(string redisKey, string hashField)
 577         {
 578             redisKey = AddKeyPrefix(redisKey);
 579             return Deserialize<T>(await _db.HashGetAsync(redisKey, hashField));
 580         }
 581 
 582         /// <summary>
 583         /// 指定键递增
 584         /// </summary>
 585         /// <param name="key"></param>
 586         /// <param name="hashField"></param>
 587         /// <param name="value"></param>
 588         /// <returns></returns>
 589         public async Task<double> HashIncrementAsync(string key, string hashField, double value = 1)
 590         {
 591             key = AddKeyPrefix(key);
 592             return await _db.HashIncrementAsync(key, hashField, value);
 593         }
 594 
 595         /// <summary>
 596         /// 指定键递减
 597         /// </summary>
 598         /// <param name="key"></param>
 599         /// <param name="hashField"></param>
 600         /// <param name="value"></param>
 601         /// <returns></returns>
 602         public async Task<double> HashDecrementAsync(string key, string hashField, double value = 1)
 603         {
 604             key = AddKeyPrefix(key);
 605             return await _db.HashDecrementAsync(key, hashField, value);
 606         }
 607 
 608         #endregion async
 609 
 610         #endregion Hash 操作
 611 
 612         #region List 操作
 613 
 614         /// <summary>
 615         /// 移除并返回存储在该键列表的第一个元素
 616         /// </summary>
 617         /// <param name="key"></param>
 618         /// <returns></returns>
 619         public string ListLeftPop(string key)
 620         {
 621             key = AddKeyPrefix(key);
 622             return _db.ListLeftPop(key);
 623         }
 624 
 625         /// <summary>
 626         /// 出列,移除并返回存储在该键列表的最后一个元素
 627         /// </summary>
 628         /// <param name="key"></param>
 629         /// <returns></returns>
 630         public string ListRightPop(string key)
 631         {
 632             key = AddKeyPrefix(key);
 633             return _db.ListRightPop(key);
 634         }
 635 
 636         /// <summary>
 637         /// 移除列表指定键上与该值相同的元素
 638         /// </summary>
 639         /// <param name="key"></param>
 640         /// <param name="value"></param>
 641         /// <returns></returns>
 642         public long ListRemove(string key, string value)
 643         {
 644             key = AddKeyPrefix(key);
 645             return _db.ListRemove(key, value);
 646         }
 647 
 648         /// <summary>
 649         /// 入列,在列表尾部插入值。如果键不存在,先创建再插入值
 650         /// </summary>
 651         /// <param name="key"></param>
 652         /// <param name="value"></param>
 653         /// <returns></returns>
 654         public long ListRightPush(string key, string value)
 655         {
 656             key = AddKeyPrefix(key);
 657             return _db.ListRightPush(key, value);
 658         }
 659 
 660         /// <summary>
 661         /// 在列表头部插入值。如果键不存在,先创建再插入值
 662         /// </summary>
 663         /// <param name="key"></param>
 664         /// <param name="value"></param>
 665         /// <returns></returns>
 666         public long ListLeftPush(string key, string value)
 667         {
 668             key = AddKeyPrefix(key);
 669             return _db.ListLeftPush(key, value);
 670         }
 671 
 672         /// <summary>
 673         /// 返回列表上该键的长度,如果不存在,返回 0
 674         /// </summary>
 675         /// <param name="key"></param>
 676         /// <returns></returns>
 677         public long ListLength(string key)
 678         {
 679             key = AddKeyPrefix(key);
 680             return _db.ListLength(key);
 681         }
 682 
 683         /// <summary>
 684         /// 返回在该列表上键所对应的元素
 685         /// </summary>
 686         /// <param name="key"></param>
 687         /// <param name="start"></param>
 688         /// <param name="stop"></param>
 689         /// <returns></returns>
 690         public IEnumerable<string> ListRange(string key, long start = 0L, long stop = -1L)
 691         {
 692             key = AddKeyPrefix(key);
 693             return ConvertStrings(_db.ListRange(key, start, stop));
 694         }
 695 
 696         /// <summary>
 697         /// 移除并返回存储在该键列表的第一个元素
 698         /// </summary>
 699         /// <param name="key"></param>
 700         /// <returns></returns>
 701         public T ListLeftPop<T>(string key)
 702         {
 703             key = AddKeyPrefix(key);
 704             return Deserialize<T>(_db.ListLeftPop(key));
 705         }
 706 
 707         /// <summary>
 708         /// 出队,移除并返回存储在该键列表的最后一个元素
 709         /// </summary>
 710         /// <param name="key"></param>
 711         /// <returns></returns>
 712         public T ListRightPop<T>(string key)
 713         {
 714             key = AddKeyPrefix(key);
 715             return Deserialize<T>(_db.ListRightPop(key));
 716         }
 717 
 718         /// <summary>
 719         /// 入队,在列表尾部插入值。如果键不存在,先创建再插入值
 720         /// </summary>
 721         /// <param name="key"></param>
 722         /// <param name="value"></param>
 723         /// <returns></returns>
 724         public long ListRightPush<T>(string key, T value)
 725         {
 726             key = AddKeyPrefix(key);
 727             return _db.ListRightPush(key, Serialize(value));
 728         }
 729 
 730         /// <summary>
 731         /// 在列表头部插入值。如果键不存在,先创建再插入值
 732         /// </summary>
 733         /// <param name="key"></param>
 734         /// <param name="value"></param>
 735         /// <returns></returns>
 736         public long ListLeftPush<T>(string key, T value)
 737         {
 738             key = AddKeyPrefix(key);
 739             return _db.ListLeftPush(key, Serialize(value));
 740         }
 741 
 742         #region List-async
 743 
 744         /// <summary>
 745         /// 移除并返回存储在该键列表的第一个元素
 746         /// </summary>
 747         /// <param name="key"></param>
 748         /// <returns></returns>
 749         public async Task<string> ListLeftPopAsync(string key)
 750         {
 751             key = AddKeyPrefix(key);
 752             return await _db.ListLeftPopAsync(key);
 753         }
 754 
 755         /// <summary>
 756         /// 移除并返回存储在该键列表的最后一个元素
 757         /// </summary>
 758         /// <param name="key"></param>
 759         /// <returns></returns>
 760         public async Task<string> ListRightPopAsync(string key)
 761         {
 762             key = AddKeyPrefix(key);
 763             return await _db.ListRightPopAsync(key);
 764         }
 765 
 766         /// <summary>
 767         /// 移除列表指定键上与该值相同的元素
 768         /// </summary>
 769         /// <param name="key"></param>
 770         /// <param name="value"></param>
 771         /// <returns></returns>
 772         public async Task<long> ListRemoveAsync(string key, string value)
 773         {
 774             key = AddKeyPrefix(key);
 775             return await _db.ListRemoveAsync(key, value);
 776         }
 777 
 778         /// <summary>
 779         /// 在列表尾部插入值。如果键不存在,先创建再插入值
 780         /// </summary>
 781         /// <param name="key"></param>
 782         /// <param name="value"></param>
 783         /// <returns></returns>
 784         public async Task<long> ListRightPushAsync(string key, string value)
 785         {
 786             key = AddKeyPrefix(key);
 787             return await _db.ListRightPushAsync(key, value);
 788         }
 789 
 790         /// <summary>
 791         /// 在列表头部插入值。如果键不存在,先创建再插入值
 792         /// </summary>
 793         /// <param name="key"></param>
 794         /// <param name="value"></param>
 795         /// <returns></returns>
 796         public async Task<long> ListLeftPushAsync(string key, string value)
 797         {
 798             key = AddKeyPrefix(key);
 799             return await _db.ListLeftPushAsync(key, value);
 800         }
 801 
 802         /// <summary>
 803         /// 返回列表上该键的长度,如果不存在,返回 0
 804         /// </summary>
 805         /// <param name="key"></param>
 806         /// <returns></returns>
 807         public async Task<long> ListLengthAsync(string key)
 808         {
 809             key = AddKeyPrefix(key);
 810             return await _db.ListLengthAsync(key);
 811         }
 812 
 813         /// <summary>
 814         /// 返回在该列表上键所对应的元素
 815         /// </summary>
 816         /// <param name="key"></param>
 817         /// <param name="start"></param>
 818         /// <param name="stop"></param>
 819         /// <returns></returns>
 820         public async Task<IEnumerable<string>> ListRangeAsync(string key, long start = 0L, long stop = -1L)
 821         {
 822             key = AddKeyPrefix(key);
 823             var query = await _db.ListRangeAsync(key, start, stop);
 824             return query.Select(x => x.ToString());
 825         }
 826 
 827         /// <summary>
 828         /// 移除并返回存储在该键列表的第一个元素
 829         /// </summary>
 830         /// <param name="key"></param>
 831         /// <returns></returns>
 832         public async Task<T> ListLeftPopAsync<T>(string key)
 833         {
 834             key = AddKeyPrefix(key);
 835             return Deserialize<T>(await _db.ListLeftPopAsync(key));
 836         }
 837 
 838         /// <summary>
 839         /// 移除并返回存储在该键列表的最后一个元素
 840         /// </summary>
 841         /// <param name="key"></param>
 842         /// <returns></returns>
 843         public async Task<T> ListRightPopAsync<T>(string key)
 844         {
 845             key = AddKeyPrefix(key);
 846             return Deserialize<T>(await _db.ListRightPopAsync(key));
 847         }
 848 
 849         /// <summary>
 850         /// 在列表尾部插入值。如果键不存在,先创建再插入值
 851         /// </summary>
 852         /// <param name="key"></param>
 853         /// <param name="value"></param>
 854         /// <returns></returns>
 855         public async Task<long> ListRightPushAsync<T>(string key, T value)
 856         {
 857             key = AddKeyPrefix(key);
 858             return await _db.ListRightPushAsync(key, Serialize(value));
 859         }
 860 
 861         /// <summary>
 862         /// 在列表头部插入值。如果键不存在,先创建再插入值
 863         /// </summary>
 864         /// <param name="key"></param>
 865         /// <param name="value"></param>
 866         /// <returns></returns>
 867         public async Task<long> ListLeftPushAsync<T>(string key, T value)
 868         {
 869             key = AddKeyPrefix(key);
 870             return await _db.ListLeftPushAsync(key, Serialize(value));
 871         }
 872 
 873         #endregion List-async
 874 
 875         #endregion List 操作
 876 
 877         #region SortedSet 操作
 878 
 879         /// <summary>
 880         /// SortedSet 新增
 881         /// </summary>
 882         /// <param name="key"></param>
 883         /// <param name="member"></param>
 884         /// <param name="score"></param>
 885         /// <returns></returns>
 886         public bool SortedSetAdd(string key, string member, double score)
 887         {
 888             key = AddKeyPrefix(key);
 889             return _db.SortedSetAdd(key, member, score);
 890         }
 891 
 892         /// <summary>
 893         /// 在有序集合中返回指定范围的元素,默认情况下从低到高。
 894         /// </summary>
 895         /// <param name="key"></param>
 896         /// <param name="start"></param>
 897         /// <param name="stop"></param>
 898         /// <param name="order"></param>
 899         /// <returns></returns>
 900         public IEnumerable<string> SortedSetRangeByRank(string key, long start = 0L, long stop = -1L,
 901             OrderType order = OrderType.Ascending)
 902         {
 903             key = AddKeyPrefix(key);
 904             return _db.SortedSetRangeByRank(key, start, stop, (Order) order).Select(x => x.ToString());
 905         }
 906 
 907         /// <summary>
 908         /// 返回有序集合的元素个数
 909         /// </summary>
 910         /// <param name="key"></param>
 911         /// <returns></returns>
 912         public long SortedSetLength(string key)
 913         {
 914             key = AddKeyPrefix(key);
 915             return _db.SortedSetLength(key);
 916         }
 917 
 918         /// <summary>
 919         /// 返回有序集合的元素个数
 920         /// </summary>
 921         /// <param name="key"></param>
 922         /// <param name="memebr"></param>
 923         /// <returns></returns>
 924         public bool SortedSetRemove(string key, string memebr)
 925         {
 926             key = AddKeyPrefix(key);
 927             return _db.SortedSetRemove(key, memebr);
 928         }
 929 
 930         /// <summary>
 931         /// SortedSet 新增
 932         /// </summary>
 933         /// <param name="key"></param>
 934         /// <param name="member"></param>
 935         /// <param name="score"></param>
 936         /// <returns></returns>
 937         public bool SortedSetAdd<T>(string key, T member, double score)
 938         {
 939             key = AddKeyPrefix(key);
 940             var json = Serialize(member);
 941 
 942             return _db.SortedSetAdd(key, json, score);
 943         }
 944 
 945         /// <summary>
 946         /// 增量的得分 排序 的集合中的成员存储键值键按增量
 947         /// </summary>
 948         /// <param name="key"></param>
 949         /// <param name="member"></param>
 950         /// <param name="value"></param>
 951         /// <returns></returns>
 952         public double SortedSetIncrement(string key, string member, double value = 1)
 953         {
 954             key = AddKeyPrefix(key);
 955             return _db.SortedSetIncrement(key, member, value);
 956         }
 957 
 958         #region SortedSet-Async
 959 
 960         /// <summary>
 961         /// SortedSet 新增
 962         /// </summary>
 963         /// <param name="key"></param>
 964         /// <param name="member"></param>
 965         /// <param name="score"></param>
 966         /// <returns></returns>
 967         public async Task<bool> SortedSetAddAsync(string key, string member, double score)
 968         {
 969             key = AddKeyPrefix(key);
 970             return await _db.SortedSetAddAsync(key, member, score);
 971         }
 972 
 973         /// <summary>
 974         /// 在有序集合中返回指定范围的元素,默认情况下从低到高。
 975         /// </summary>
 976         /// <param name="key"></param>
 977         /// <returns></returns>
 978         public async Task<IEnumerable<string>> SortedSetRangeByRankAsync(string key)
 979         {
 980             key = AddKeyPrefix(key);
 981             return ConvertStrings(await _db.SortedSetRangeByRankAsync(key));
 982         }
 983 
 984         /// <summary>
 985         /// 返回有序集合的元素个数
 986         /// </summary>
 987         /// <param name="key"></param>
 988         /// <returns></returns>
 989         public async Task<long> SortedSetLengthAsync(string key)
 990         {
 991             key = AddKeyPrefix(key);
 992             return await _db.SortedSetLengthAsync(key);
 993         }
 994 
 995         /// <summary>
 996         /// 返回有序集合的元素个数
 997         /// </summary>
 998         /// <param name="key"></param>
 999         /// <param name="memebr"></param>
1000         /// <returns></returns>
1001         public async Task<bool> SortedSetRemoveAsync(string key, string memebr)
1002         {
1003             key = AddKeyPrefix(key);
1004             return await _db.SortedSetRemoveAsync(key, memebr);
1005         }
1006 
1007         /// <summary>
1008         /// SortedSet 新增
1009         /// </summary>
1010         /// <param name="key"></param>
1011         /// <param name="member"></param>
1012         /// <param name="score"></param>
1013         /// <returns></returns>
1014         public async Task<bool> SortedSetAddAsync<T>(string key, T member, double score)
1015         {
1016             key = AddKeyPrefix(key);
1017             var json = Serialize(member);
1018 
1019             return await _db.SortedSetAddAsync(key, json, score);
1020         }
1021 
1022         /// <summary>
1023         /// 增量的得分排序的集合中的成员存储键值键按增量
1024         /// </summary>
1025         /// <param name="key"></param>
1026         /// <param name="member"></param>
1027         /// <param name="value"></param>
1028         /// <returns></returns>
1029         public Task<double> SortedSetIncrementAsync(string key, string member, double value = 1)
1030         {
1031             key = AddKeyPrefix(key);
1032             return _db.SortedSetIncrementAsync(key, member, value);
1033         }
1034 
1035         #endregion SortedSet-Async
1036 
1037         #endregion SortedSet 操作
1038 
1039         #region key 操作
1040 
1041         /// <summary>
1042         /// 移除指定 Key
1043         /// </summary>
1044         /// <param name="key"></param>
1045         /// <returns></returns>
1046         public bool KeyDelete(string key)
1047         {
1048             key = AddKeyPrefix(key);
1049             return _db.KeyDelete(key);
1050         }
1051 
1052         /// <summary>
1053         /// 移除指定 Key
1054         /// </summary>
1055         /// <param name="keys"></param>
1056         /// <returns></returns>
1057         public long KeyDelete(IEnumerable<string> keys)
1058         {
1059             var redisKeys = keys.Select(x => (RedisKey) AddKeyPrefix(x));
1060             return _db.KeyDelete(redisKeys.ToArray());
1061         }
1062 
1063         /// <summary>
1064         /// 校验 Key 是否存在
1065         /// </summary>
1066         /// <param name="key"></param>
1067         /// <returns></returns>
1068         public bool KeyExists(string key)
1069         {
1070             key = AddKeyPrefix(key);
1071             return _db.KeyExists(key);
1072         }
1073 
1074         /// <summary>
1075         /// 重命名 Key
1076         /// </summary>
1077         /// <param name="key"></param>
1078         /// <param name="newKey"></param>
1079         /// <returns></returns>
1080         public bool KeyRename(string key, string newKey)
1081         {
1082             key = AddKeyPrefix(key);
1083             return _db.KeyRename(key, newKey);
1084         }
1085 
1086         /// <summary>
1087         /// 设置 Key 的时间
1088         /// </summary>
1089         /// <param name="key"></param>
1090         /// <param name="expiry"></param>
1091         /// <returns></returns>
1092         public bool KeyExpire(string key, TimeSpan? expiry)
1093         {
1094             key = AddKeyPrefix(key);
1095             return _db.KeyExpire(key, expiry);
1096         }
1097 
1098         #region key-async
1099 
1100         /// <summary>
1101         /// 移除指定 Key
1102         /// </summary>
1103         /// <param name="key"></param>
1104         /// <returns></returns>
1105         public async Task<bool> KeyDeleteAsync(string key)
1106         {
1107             key = AddKeyPrefix(key);
1108             return await _db.KeyDeleteAsync(key);
1109         }
1110 
1111         /// <summary>
1112         /// 移除指定 Key
1113         /// </summary>
1114         /// <param name="keys"></param>
1115         /// <returns></returns>
1116         public async Task<long> KeyDeleteAsync(IEnumerable<string> keys)
1117         {
1118             var redisKeys = keys.Select(x => (RedisKey) AddKeyPrefix(x));
1119             return await _db.KeyDeleteAsync(redisKeys.ToArray());
1120         }
1121 
1122         /// <summary>
1123         /// 校验 Key 是否存在
1124         /// </summary>
1125         /// <param name="key"></param>
1126         /// <returns></returns>
1127         public async Task<bool> KeyExistsAsync(string key)
1128         {
1129             key = AddKeyPrefix(key);
1130             return await _db.KeyExistsAsync(key);
1131         }
1132 
1133         /// <summary>
1134         /// 重命名 Key
1135         /// </summary>
1136         /// <param name="key"></param>
1137         /// <param name="newKey"></param>
1138         /// <returns></returns>
1139         public async Task<bool> KeyRenameAsync(string key, string newKey)
1140         {
1141             key = AddKeyPrefix(key);
1142             return await _db.KeyRenameAsync(key, newKey);
1143         }
1144 
1145         /// <summary>
1146         /// 设置 Key 的时间
1147         /// </summary>
1148         /// <param name="key"></param>
1149         /// <param name="expiry"></param>
1150         /// <returns></returns>
1151         public async Task<bool> KeyExpireAsync(string key, TimeSpan? expiry)
1152         {
1153             key = AddKeyPrefix(key);
1154             return await _db.KeyExpireAsync(key, expiry);
1155         }
1156 
1157         #endregion key-async
1158 
1159         #endregion key 操作
1160 
1161         #region 发布订阅
1162 
1163         /// <summary>
1164         /// 订阅
1165         /// </summary>
1166         /// <param name="channel"></param>
1167         /// <param name="handle"></param>
1168         public void Subscribe(RedisChannel channel, Action<RedisChannel, RedisValue> handle)
1169         {
1170             var sub = _connMultiplexer.GetSubscriber();
1171             sub.Subscribe(channel, handle);
1172         }
1173 
1174         /// <summary>
1175         /// 发布
1176         /// </summary>
1177         /// <param name="channel"></param>
1178         /// <param name="message"></param>
1179         /// <returns></returns>
1180         public long Publish(RedisChannel channel, RedisValue message)
1181         {
1182             var sub = _connMultiplexer.GetSubscriber();
1183             return sub.Publish(channel, message);
1184         }
1185 
1186         /// <summary>
1187         /// 发布(使用序列化)
1188         /// </summary>
1189         /// <typeparam name="T"></typeparam>
1190         /// <param name="channel"></param>
1191         /// <param name="message"></param>
1192         /// <returns></returns>
1193         public long Publish<T>(RedisChannel channel, T message)
1194         {
1195             var sub = _connMultiplexer.GetSubscriber();
1196             return sub.Publish(channel, Serialize(message));
1197         }
1198 
1199         #region 发布订阅-async
1200 
1201         /// <summary>
1202         /// 订阅
1203         /// </summary>
1204         /// <param name="channel"></param>
1205         /// <param name="handle"></param>
1206         public async Task SubscribeAsync(RedisChannel channel, Action<RedisChannel, RedisValue> handle)
1207         {
1208             var sub = _connMultiplexer.GetSubscriber();
1209             await sub.SubscribeAsync(channel, handle);
1210         }
1211 
1212         /// <summary>
1213         /// 发布
1214         /// </summary>
1215         /// <param name="channel"></param>
1216         /// <param name="message"></param>
1217         /// <returns></returns>
1218         public async Task<long> PublishAsync(RedisChannel channel, RedisValue message)
1219         {
1220             var sub = _connMultiplexer.GetSubscriber();
1221             return await sub.PublishAsync(channel, message);
1222         }
1223 
1224         /// <summary>
1225         /// 发布(使用序列化)
1226         /// </summary>
1227         /// <typeparam name="T"></typeparam>
1228         /// <param name="channel"></param>
1229         /// <param name="message"></param>
1230         /// <returns></returns>
1231         public async Task<long> PublishAsync<T>(RedisChannel channel, T message)
1232         {
1233             var sub = _connMultiplexer.GetSubscriber();
1234             return await sub.PublishAsync(channel, Serialize(message));
1235         }
1236 
1237         #endregion 发布订阅-async
1238 
1239         #endregion 发布订阅
1240 
1241         #region private method
1242 
1243         /// <summary>
1244         /// 添加 Key 的前缀
1245         /// </summary>
1246         /// <param name="key"></param>
1247         /// <returns></returns>
1248         private static string AddKeyPrefix(string key)
1249         {
1250             return $"{DefaultKey}:{key}";
1251         }
1252 
1253         /// <summary>
1254         /// 转换为字符串
1255         /// </summary>
1256         /// <typeparam name="T"></typeparam>
1257         /// <param name="list"></param>
1258         /// <returns></returns>
1259         private static IEnumerable<string> ConvertStrings<T>(IEnumerable<T> list) where T : struct
1260         {
1261             if (list == null) throw new ArgumentNullException(nameof(list));
1262             return list.Select(x => x.ToString());
1263         }
1264 
1265         #region 注册事件
1266 
1267         /// <summary>
1268         /// 添加注册事件
1269         /// </summary>
1270         private static void AddRegisterEvent()
1271         {
1272             _connMultiplexer.ConnectionRestored += ConnMultiplexer_ConnectionRestored;
1273             _connMultiplexer.ConnectionFailed += ConnMultiplexer_ConnectionFailed;
1274             _connMultiplexer.ErrorMessage += ConnMultiplexer_ErrorMessage;
1275             _connMultiplexer.ConfigurationChanged += ConnMultiplexer_ConfigurationChanged;
1276             _connMultiplexer.HashSlotMoved += ConnMultiplexer_HashSlotMoved;
1277             _connMultiplexer.InternalError += ConnMultiplexer_InternalError;
1278             _connMultiplexer.ConfigurationChangedBroadcast += ConnMultiplexer_ConfigurationChangedBroadcast;
1279         }
1280 
1281         /// <summary>
1282         /// 重新配置广播时(通常意味着主从同步更改)
1283         /// </summary>
1284         /// <param name="sender"></param>
1285         /// <param name="e"></param>
1286         private static void ConnMultiplexer_ConfigurationChangedBroadcast(object sender, EndPointEventArgs e)
1287         {
1288             Console.WriteLine($"{nameof(ConnMultiplexer_ConfigurationChangedBroadcast)}: {e.EndPoint}");
1289         }
1290 
1291         /// <summary>
1292         /// 发生内部错误时(主要用于调试)
1293         /// </summary>
1294         /// <param name="sender"></param>
1295         /// <param name="e"></param>
1296         private static void ConnMultiplexer_InternalError(object sender, InternalErrorEventArgs e)
1297         {
1298             Console.WriteLine($"{nameof(ConnMultiplexer_InternalError)}: {e.Exception}");
1299         }
1300 
1301         /// <summary>
1302         /// 更改集群时
1303         /// </summary>
1304         /// <param name="sender"></param>
1305         /// <param name="e"></param>
1306         private static void ConnMultiplexer_HashSlotMoved(object sender, HashSlotMovedEventArgs e)
1307         {
1308             Console.WriteLine(
1309                 $"{nameof(ConnMultiplexer_HashSlotMoved)}: {nameof(e.OldEndPoint)}-{e.OldEndPoint} To {nameof(e.NewEndPoint)}-{e.NewEndPoint}, ");
1310         }
1311 
1312         /// <summary>
1313         /// 配置更改时
1314         /// </summary>
1315         /// <param name="sender"></param>
1316         /// <param name="e"></param>
1317         private static void ConnMultiplexer_ConfigurationChanged(object sender, EndPointEventArgs e)
1318         {
1319             Console.WriteLine($"{nameof(ConnMultiplexer_ConfigurationChanged)}: {e.EndPoint}");
1320         }
1321 
1322         /// <summary>
1323         /// 发生错误时
1324         /// </summary>
1325         /// <param name="sender"></param>
1326         /// <param name="e"></param>
1327         private static void ConnMultiplexer_ErrorMessage(object sender, RedisErrorEventArgs e)
1328         {
1329             Console.WriteLine($"{nameof(ConnMultiplexer_ErrorMessage)}: {e.Message}");
1330         }
1331 
1332         /// <summary>
1333         /// 物理连接失败时
1334         /// </summary>
1335         /// <param name="sender"></param>
1336         /// <param name="e"></param>
1337         private static void ConnMultiplexer_ConnectionFailed(object sender, ConnectionFailedEventArgs e)
1338         {
1339             Console.WriteLine($"{nameof(ConnMultiplexer_ConnectionFailed)}: {e.Exception}");
1340         }
1341 
1342         /// <summary>
1343         /// 建立物理连接时
1344         /// </summary>
1345         /// <param name="sender"></param>
1346         /// <param name="e"></param>
1347         private static void ConnMultiplexer_ConnectionRestored(object sender, ConnectionFailedEventArgs e)
1348         {
1349             Console.WriteLine($"{nameof(ConnMultiplexer_ConnectionRestored)}: {e.Exception}");
1350         }
1351 
1352         #endregion 注册事件
1353 
1354         /// <summary>
1355         /// 序列化
1356         /// </summary>
1357         /// <param name="obj"></param>
1358         /// <returns></returns>
1359         private static byte[] Serialize(object obj)
1360         {
1361             if (obj == null)
1362                 return null;
1363 
1364             var binaryFormatter = new BinaryFormatter();
1365             using (var memoryStream = new MemoryStream())
1366             {
1367                 binaryFormatter.Serialize(memoryStream, obj);
1368                 var data = memoryStream.ToArray();
1369                 return data;
1370             }
1371         }
1372 
1373         /// <summary>
1374         /// 反序列化
1375         /// </summary>
1376         /// <typeparam name="T"></typeparam>
1377         /// <param name="data"></param>
1378         /// <returns></returns>
1379         private static T Deserialize<T>(byte[] data)
1380         {
1381             if (data == null)
1382                 return default(T);
1383 
1384             var binaryFormatter = new BinaryFormatter();
1385             using (var memoryStream = new MemoryStream(data))
1386             {
1387                 var result = (T) binaryFormatter.Deserialize(memoryStream);
1388                 return result;
1389             }
1390         }
1391 
1392         #endregion private method
1393     }
1394 }

RedisHelper.cs

Redis 小白指南(一)


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

第二次机器革命

第二次机器革命

[美]埃里克·布莱恩约弗森 / 蒋永军 / 中信出版社 / 2014-9 / 59.80

“一本非常鼓舞人心的书!”——托马斯•L•弗里德曼 《世界是平的》作者 一场革命开始了! 在《第二次机器革命》这本书中,埃里克•布莱恩约弗森和安德鲁•麦卡菲——这两位处于数字技术时代最前沿的思想家,向我们阐述了驱动我们经济和生活的发生变革的力量。他们认为,数字技术将会给我们带来难以想象的巨大变革:想象一下令人眩目的个人数字技术产品、一流的基础设施,都将会给我们带来极大的便利。数字技术(......一起来看看 《第二次机器革命》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试