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 小白指南(一)


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

查看所有标签

猜你喜欢:

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

Head First Rails

Head First Rails

David Griffiths / O'Reilly Media / 2008-12-30 / USD 49.99

Figure its about time that you hop on the Ruby on Rails bandwagon? You've heard that it'll increase your productivity exponentially, and allow you to created full fledged web applications with minimal......一起来看看 《Head First Rails》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具