//从第1个开始,依次向左插入值。如果键不存在,先创建再插入值  队列形式 先进后出,后进先出
//插入后形式  <-- 10,9,8,7,6,5,4,3,2,1 <-- 方向向左依次进行
stopwatch.Start();
for (int i = ; i < ; i++)
{
var getobjlist = RedisCacheHelper.Instance.ListLeftPush("leftlistkey", (i + ).ToString());
}
stopwatch.Stop();
Console.WriteLine("在列表头部插入值消耗时间:" + stopwatch.ElapsedMilliseconds.ToString()); //从第1个开始,依次向右插入值。如果键不存在,先创建再插入值 先进先出,后进后出
//插入后形式  1,2,3,4,5,6,7,8,9,10 --> 方向向右依次进行
stopwatch.Start();
for (int i = ; i < ; i++)
{
var getobjlist = RedisCacheHelper.Instance.ListRightPush("rightlistkey", (i + ).ToString());
}
stopwatch.Stop();
Console.WriteLine("在列表尾部插入值消耗时间:" + stopwatch.ElapsedMilliseconds.ToString());

            //获取Left列表中的队列元素  从列表头部开始读取
var getleftvalue = RedisCacheHelper.Instance.ListRange("leftlistkey");
Console.WriteLine(string.Join(",", getleftvalue)); //获取Right列表中的队列元素 从列表头部开始读取
var getrightvalue = RedisCacheHelper.Instance.ListRange("rightlistkey");
Console.WriteLine(string.Join(",", getrightvalue));

            //从左边第一个元素开始  循环移除并返回该移除的值
Console.WriteLine("从左边开始");
while (true)
{
var getleftvalue = RedisCacheHelper.Instance.ListLeftPop("leftlistkey");
if (!string.IsNullOrEmpty(getleftvalue))
{
Console.WriteLine("移除:" + getleftvalue);
}
else
{
break;
}
} //从右边第一个元素开始 循环移除并返回该移除的值
Console.WriteLine("从右边开始");
while (true)
{
var getrightvalue = RedisCacheHelper.Instance.ListRightPop("rightlistkey");
if (!string.IsNullOrEmpty(getrightvalue))
{
Console.WriteLine("移除:" + getrightvalue);
}
else
{
break;
}
}

            //从左边第一个元素开始  循环移除并返回该移除的值  替换一下Key后
Console.WriteLine("从左边开始");
while (true)
{
var getleftvalue = RedisCacheHelper.Instance.ListLeftPop("rightlistkey");
if (!string.IsNullOrEmpty(getleftvalue))
{
Console.WriteLine("移除:" + getleftvalue);
}
else
{
break;
}
} //从右边第一个元素开始 循环移除并返回该移除的值 替换一下Key后
Console.WriteLine("从右边开始");
while (true)
{
var getrightvalue = RedisCacheHelper.Instance.ListRightPop("leftlistkey");
if (!string.IsNullOrEmpty(getrightvalue))
{
Console.WriteLine("移除:" + getrightvalue);
}
else
{
break;
}
}

            //列表长度  不存在则返回0
var getlength = RedisCacheHelper.Instance.ListLength("leftlistkey");
Console.WriteLine("列表长度:" + getlength); //删除List中的元素 并返回删除的个数 不存在则返回0
var getlong = RedisCacheHelper.Instance.ListDelRange("leftlistkey", "");
Console.WriteLine("删除List中的元素,并返回删除的个数:" + getlong); //清空列表
RedisCacheHelper.Instance.ListClear("leftlistkey");

使用List类型 模拟用户并发抢购商品

//模拟数据  想List类型表中加入一定数量的库存   50个商品
for (int i = ; i <= ; i++)
{
var getvalue = RedisCacheHelper.Instance.ListRightPush("orderlist", i.ToString());
//Console.WriteLine("返回结果:" + getvalue);
} //模拟创建多个用户 100个用户
List<TestRedis> testlist = new List<TestRedis>();
for (int i = ; i < ; i++)
{
testlist.Add(new TestRedis() { Uid = (i + ) });
} //先清空
RedisCacheHelper.Instance.ListClear("orderSuccessList"); //使用List类型模拟并发情况 不用担心库存为负的情况
//模拟多个用户抢购限时商品 100个用户抢50个商品
stopwatch.Start();
List<Task> taskList = new List<Task>();
foreach (var item in testlist)
{
var task = Task.Run(() =>
{
try
{
//先自减,获取自减后的值
long order_Num = -;
long.TryParse(RedisCacheHelper.Instance.ListRightPop("orderlist"), out order_Num);
if (order_Num > )
{
//下面执行订单逻辑(这里不考虑业务出错的情况) RedisCacheHelper.Instance.ListLeftPush("orderSuccessList", item.Uid.ToString()); //记录下单成功的用户 //操作数据库相关逻辑 可以使用“消息队列”或“服务”进行数据库同步操作 Console.WriteLine("用户:" + item.Uid + ",抢到了商品:" + order_Num);
}
else
{
Console.WriteLine("商品已经被抢光了,用户" + item.Uid + "未抢到");
} }
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw;
}
});
taskList.Add(task);
}
Task.WaitAll(taskList.ToArray());
stopwatch.Stop();
Console.WriteLine("模拟并发场景消耗时间:" + stopwatch.ElapsedMilliseconds.ToString());

应用场景:

Redis list 的应用场景非常多,也是 Redis 最重要的数据结构之一,比如 twitter 的关注列表,粉丝列表等都可以用 Redis 的 list 结构来实现,比较好理解,这里不再重复。

实现方式:

Redis list 的实现为一个双向链表,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销,Redis 内部的很多实现,包括发送缓冲队列等也都是用的这个数据结构。

最后附上Helper

        /// <summary>
/// 在列表头部插入值。如果键不存在,先创建再插入值
/// </summary>
/// <param name="redisKey"></param>
/// <param name="redisValue"></param>
/// <returns></returns>
public long ListLeftPush(string redisKey, string redisValue, int db = -)
{
var _db = GetDatabase(db);
return _db.ListLeftPush(redisKey, redisValue);
}
/// <summary>
/// 在列表尾部插入值。如果键不存在,先创建再插入值
/// </summary>
/// <param name="redisKey"></param>
/// <param name="redisValue"></param>
/// <returns></returns>
public long ListRightPush(string redisKey, string redisValue, int db = -)
{
var _db = GetDatabase(db);
return _db.ListRightPush(redisKey, redisValue);
} /// <summary>
/// 在列表尾部插入数组集合。如果键不存在,先创建再插入值
/// </summary>
/// <param name="redisKey"></param>
/// <param name="redisValue"></param>
/// <returns></returns>
public long ListRightPush(string redisKey, IEnumerable<string> redisValue, int db = -)
{
var _db = GetDatabase(db);
var redislist = new List<RedisValue>();
foreach (var item in redisValue)
{
redislist.Add(item);
}
return _db.ListRightPush(redisKey, redislist.ToArray());
} /// <summary>
/// 移除并返回存储在该键列表的第一个元素 反序列化
/// </summary>
/// <param name="redisKey"></param>
/// <returns></returns>
public T ListLeftPop<T>(string redisKey, int db = -) where T : class
{
var _db = GetDatabase(db);
return JsonConvert.DeserializeObject<T>(_db.ListLeftPop(redisKey));
} /// <summary>
/// 移除并返回存储在该键列表的最后一个元素 反序列化
/// 只能是对象集合
/// </summary>
/// <param name="redisKey"></param>
/// <returns></returns>
public T ListRightPop<T>(string redisKey, int db = -) where T : class
{
var _db = GetDatabase(db);
return JsonConvert.DeserializeObject<T>(_db.ListRightPop(redisKey));
} /// <summary>
/// 移除并返回存储在该键列表的第一个元素
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="redisKey"></param>
/// <param name="db"></param>
/// <returns></returns>
public string ListLeftPop(string redisKey, int db = -)
{
var _db = GetDatabase(db);
return _db.ListLeftPop(redisKey);
} /// <summary>
/// 移除并返回存储在该键列表的最后一个元素
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="redisKey"></param>
/// <param name="db"></param>
/// <returns></returns>
public string ListRightPop(string redisKey, int db = -)
{
var _db = GetDatabase(db);
return _db.ListRightPop(redisKey);
} /// <summary>
/// 列表长度
/// </summary>
/// <param name="redisKey"></param>
/// <param name="db"></param>
/// <returns></returns>
public long ListLength(string redisKey, int db = -)
{
var _db = GetDatabase(db);
return _db.ListLength(redisKey);
} /// <summary>
/// 返回在该列表上键所对应的元素
/// </summary>
/// <param name="redisKey"></param>
/// <returns></returns>
public IEnumerable<string> ListRange(string redisKey, int db = -)
{
var _db = GetDatabase(db);
var result = _db.ListRange(redisKey);
return result.Select(o => o.ToString());
} /// <summary>
/// 根据索引获取指定位置数据
/// </summary>
/// <param name="redisKey"></param>
/// <param name="start"></param>
/// <param name="stop"></param>
/// <param name="db"></param>
/// <returns></returns>
public IEnumerable<string> ListRange(string redisKey, int start, int stop, int db = -)
{
var _db = GetDatabase(db);
var result = _db.ListRange(redisKey, start, stop);
return result.Select(o => o.ToString());
} /// <summary>
/// 删除List中的元素 并返回删除的个数
/// </summary>
/// <param name="redisKey">key</param>
/// <param name="redisValue">元素</param>
/// <param name="type">大于零 : 从表头开始向表尾搜索,小于零 : 从表尾开始向表头搜索,等于零:移除表中所有与 VALUE 相等的值</param>
/// <param name="db"></param>
/// <returns></returns>
public long ListDelRange(string redisKey, string redisValue, long type = , int db = -)
{
var _db = GetDatabase(db);
return _db.ListRemove(redisKey, redisValue, type);
} /// <summary>
/// 清空List
/// </summary>
/// <param name="redisKey"></param>
/// <param name="db"></param>
public void ListClear(string redisKey, int db = -)
{
var _db = GetDatabase(db);
_db.ListTrim(redisKey, , );
}

StackExchange.Redis 之 List队列 类型示例的更多相关文章

  1. StackExchange.Redis 之 Set集合 类型示例

    话不多说直接上代码: // set添加单个元素 stopwatch.Start(); "); stopwatch.Stop(); Console.WriteLine("set添加单 ...

  2. StackExchange.Redis 之 hash 类型示例

    StackExchange.Redis 的组件封装示例网上有很多,自行百度搜索即可. 这里只演示如何使用Hash类型操作数据: // 在 hash 中存入或修改一个值 并设置order_hashkey ...

  3. 怎样在Redis通过StackExchange.Redis 存储集合类型List

    StackExchange 是由StackOverFlow出品, 是对Redis的.NET封装,被越来越多的.NET开发者使用在项目中. 绝大部分原先使用ServiceStack的开发者逐渐都转了过来 ...

  4. 利用StackExchange.Redis和Log4Net构建日志队列

    简介:本文是一个简单的demo用于展示利用StackExchange.Redis和Log4Net构建日志队列,为高并发日志处理提供一些思路. 0.先下载安装Redis服务,然后再服务列表里启动服务(R ...

  5. StackExchange.Redis帮助类解决方案RedisRepository封装(字符串类型数据操作)

    本文版权归博客园和作者本人共同所有,转载和爬虫请注明原文链接 http://www.cnblogs.com/tdws/tag/NoSql/ 目录 一.基础配置封装 二.String字符串类型数据操作封 ...

  6. .NetCore使用Redis,StackExchange.Redis队列,发布与订阅,分布式锁的简单使用

    环境:之前一直是使用serverStack.Redis的客服端,今天来使用一下StackExchange.Redis(个人感觉更加的人性化一些,也是免费的,性能也不会差太多),版本为StackExch ...

  7. 深入理解MVC C#+HtmlAgilityPack+Dapper走一波爬虫 StackExchange.Redis 二次封装 C# WPF 用MediaElement控件实现视频循环播放 net 异步与同步

    深入理解MVC   MVC无人不知,可很多程序员对MVC的概念的理解似乎有误,换言之他们一直在错用MVC,尽管即使如此软件也能被写出来,然而软件内部代码的组织方式却是不科学的,这会影响到软件的可维护性 ...

  8. StackExchange.Redis 使用资料

    在StackExchange.Redis中最重要的对象是ConnectionMultiplexer类, 它存在于StackExchange.redis命名空间中.这个类隐藏了Redis服务的操作细节, ...

  9. Redis 详解 (一) StackExchange.Redis Client

    这期我们来看StackExchange.Redis,这是redis 的.net客户端之一.Redis是一个开源的内存数据存储,可以用来做数据库,缓存或者消息代理服务.目前有不少人在使用ServiceS ...

随机推荐

  1. 遗传编程GP-地图路径寻路

    本文介绍的是基于GP,并非A*算法,算是另类实现吧. 先看看地图定义,在文本文件中定义如下字符串,代表30列11行大小的地图 初始位置在左上角(0,0) ,值为1的是允许走的通的路,目标位置为右下角( ...

  2. [bzoj4825] [loj#2018] [Hnoi2017] 单旋

    Description \(H\) 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构.伸展树(\(splay\))是一种数据 结构,因为代码好写,功能多,效率高,掌握这种数据结构 ...

  3. [bzoj4446] [loj#2009] [Scoi2015] 小凸玩密室

    Description 小凸和小方相约玩密室逃脱,这个密室是一棵有 \(n\) 个节点的完全二叉树,每个节点有一个灯泡.点亮所有灯泡即可逃出密室.每个灯泡有个权值 \(Ai\) ,每条边也有个权值 \ ...

  4. 【javaWeb】HttpServletRequest常用获取URL的方法

    1.request.getRequestURL() 返回的是完整的url,包括Http协议,端口号,servlet名字和映射路径,但它不包含请求参数. 2.request.getRequestURI( ...

  5. 【javaScript】加减乘除的精确计算

    在js中使用"+"."-"等符号进行运算会出现很大的误差,所以需要自己创建函数进行精确运算. //说明:javascript的加法结果会有误差,在两个浮点数相加 ...

  6. 神器| 这款软件让win系统像Mac系统一样的好用!

    每天进步一丢丢,连接梦与想 输不起的人,往往就是赢不了的人 使用过 Mac OS X 系统的朋友可能都会使用过自带的 Quick Look 快速预览功能,用鼠标选中一个文件后,再按下键盘空格键就会弹出 ...

  7. 解决warning: #181-D: argument is incompatible with corresponding format string conversion警告

    uint8_t NetRSSI=0;uint8_t NetBer=0;uint8_t failtime=0; sscanf(&USART_RX_BUF[0],"%*s%u,%u&qu ...

  8. Pileup 格式详细说明

    转自: https://blog.csdn.net/herokoking/article/details/79276939 Pileup 格式最初是由Sanger Institute的Tony Cox ...

  9. 奇葩报错0xc0000142

    电脑突然蓝屏了一次,后来软件就打不开了,显示无法启动 网上找了一下说估计是蓝屏出现了一些问题注册表信息被删了,让输入命令重新加载一回注册表信息 for %1 in (%windir%\system32 ...

  10. 基于 H5 和 webGL 的 3d 智慧城市

    前言 中共中央.国务院在今年12月印发了<长江三角洲区域一体化发展规划纲要>(下文简称<纲要>),并发出通知,要求各地区各部门结合实际认真贯彻落实. <纲要>强调, ...