//从第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. Egret学习-TiledMap使用

    环境说明: 引擎版本:5.2.4 Egret Wing 4.1.6 1.下载依赖,下载地址https://github.com/egret-labs/egret-game-library/tree/m ...

  2. 「 神器 」资源管理神器Clover,风一样的效率

    开开心心地上班,这时你得打开我的电脑,点进D盘,打开某个项目;然后还得打开XX文档,还有- 最后的最后,你的桌面便成了这个样子 每天你都得天打开多个文件夹,切换时找文件找的晕头转向而烦恼. 每天层层深 ...

  3. 关于PDF阅读器

    获取流程 1.点击下载xodo 2.跳转到如下界面,单击箭头所指的版本: 3.单击转到 中国-中文 4.点击获取 5.在跳出来的界面点击红框 6.打开本机的Microsoft Store下载应用 介绍 ...

  4. POJ Expanding Rods

    点击打开题目 题目大意 给定L,n,C,L为红色线段,L(1+n*C)为绿色弧,求两者中点的距离 二分圆心角度数,接下来就是几何的能力了 根据正弦定理,可得: Lsinθ=rsin(90°−θ) 则弧 ...

  5. 【WPF学习】第十九章 控件类

    WPF窗口充满了各种元素,但这些元素中只有一部分是控件.在WPF领域,控件通常被描述为与用户交互的元素——能接收焦点并接受键盘或鼠标输入的元素.明显的例子包括文本框和按钮.然而,这个区别有时有些模糊. ...

  6. H.264原理

    前言 H264视频压缩算法现在无疑是所有视频压缩技术中使用最广泛,最流行的.随着 x264/openh264以及ffmpeg等开源库的推出,大多数使用者无需再对H264的细节做过多的研究,这大降低了人 ...

  7. SqlServer 利用游标批量更新数据

    SqlServer 利用游标批量更新数据 Intro 游标在有时候会很有用,在更新一部分不多的数据时,可以很方便的更新数据,不需要再写一个小工具来做了,直接写 SQL 就可以了 Sample 下面来看 ...

  8. 曹工说Spring Boot源码(15)-- Spring从xml文件里到底得到了什么(context:load-time-weaver 完整解析)

    写在前面的话 相关背景及资源: 曹工说Spring Boot源码(1)-- Bean Definition到底是什么,附spring思维导图分享 曹工说Spring Boot源码(2)-- Bean ...

  9. 1-NoSQL介绍及Redis安装

    背景 随着互联网的不断发展和软件架构的不断复杂化,同时随着网站访问量的日渐上升,导致传统单机关系型数据库应用已经无法满足人们的需求,在高并发的场景下,频繁的数据库存取操作使得服务器压力剧增,甚至导致服 ...

  10. RestTemplate远程调用方法

    概述: spring框架提供的RestTemplate类可用于在应用中调用rest服务,它简化了与http服务的通信方式,统一了RESTful的标准,封装了http链接, 我们只需要传入url及返回值 ...