C#实现简单的内存缓存

在开发过程中,我们经常需要使用缓存来提高应用程序的性能。本文将介绍如何使用C#实现一个简单的内存缓存系统,它模仿了Redis的部分基本功能

功能:

  • 基本的键值存储
  • 支持过期时间
  • 支持泛型类型
  • Hash 类型操作
  • 线程安全
  • 清理过期项

优点:

  • 不依赖第三方库
  • 实现简单
  • 内存操作,速度快
  • 支持基本的 Redis 功能

限制:

  • 数据存储在内存中,程序重启后数据会丢失
  • 不支持分布式
  • 功能相对简单

代码实现:

using System.Collections.Concurrent;namespace SimpleRedisApp
{public interface ISimpleRedis{bool Set<T>(string key, T value, TimeSpan? expiry = null);T Get<T>(string key);bool Delete(string key);bool Exists(string key);List<string> GetAllKeys();bool HashSet(string key, string field, object value);T HashGet<T>(string key, string field);void RemoveExpiredItems();}/// <summary>/// 简单的内存缓存实现/// </summary>public class SimpleRedis : ISimpleRedis{// 使用ConcurrentDictionary保证线程安全private static readonly ConcurrentDictionary<string, CacheItem> Cache = new ConcurrentDictionary<string, CacheItem>();// 缓存项类,包含值和过期时间private class CacheItem{public object Value { get; set; }public DateTime? ExpireTime { get; set; }}/// <summary>/// 设置缓存/// </summary>public bool Set<T>(string key, T value, TimeSpan? expiry = null){var item = new CacheItem{Value = value,ExpireTime = expiry.HasValue ? DateTime.Now.Add(expiry.Value) : null};Cache.AddOrUpdate(key, item, (k, old) => item);return true;}/// <summary>/// 获取缓存/// </summary>public T Get<T>(string key){if (Cache.TryGetValue(key, out CacheItem item)){if (item.ExpireTime.HasValue && item.ExpireTime.Value < DateTime.Now){// 已过期,删除并返回默认值Cache.TryRemove(key, out _);return default(T);}return (T)item.Value;}return default(T);}/// <summary>/// 删除缓存/// </summary>public bool Delete(string key){return Cache.TryRemove(key, out _);}/// <summary>/// 判断键是否存在/// </summary>public bool Exists(string key){return Cache.ContainsKey(key) &&(!Cache[key].ExpireTime.HasValue || Cache[key].ExpireTime.Value > DateTime.Now);}/// <summary>/// 清空所有缓存/// </summary>public void Clear(){Cache.Clear();}/// <summary>/// 获取所有键/// </summary>public List<string> GetAllKeys(){return Cache.Keys.ToList();}/// <summary>/// 设置Hash/// </summary>public bool HashSet(string key, string field, object value){var hash = Get<Dictionary<string, object>>(key) ?? new Dictionary<string, object>();hash[field] = value;return Set(key, hash);}/// <summary>/// 获取Hash/// </summary>public T HashGet<T>(string key, string field){var hash = Get<Dictionary<string, object>>(key);if (hash != null && hash.ContainsKey(field)){return (T)hash[field];}return default(T);}/// <summary>/// 删除过期的缓存项/// </summary>public void RemoveExpiredItems(){var now = DateTime.Now;var expiredKeys = Cache.Where(kvp =>kvp.Value.ExpireTime.HasValue &&kvp.Value.ExpireTime.Value < now).Select(kvp => kvp.Key).ToList();foreach (var key in expiredKeys){Cache.TryRemove(key, out _);}}}public class User{public string Name { get; set; }public int Age { get; set; }}internal class Program{static void Main(string[] args){var redis = new SimpleRedis();// 字符串操作redis.Set("name", "张三", TimeSpan.FromMinutes(1));var name = redis.Get<string>("name");Console.WriteLine($"Name: {name}");// 对象操作var user = new User { Name = "李四", Age = 25 };redis.Set("user:1", user);var savedUser = redis.Get<User>("user:1");Console.WriteLine($"User: {savedUser.Name}, {savedUser.Age}");// Hash操作redis.HashSet("user:2", "name", "王五");redis.HashSet("user:2", "age", 30);var userName = redis.HashGet<string>("user:2", "name");var userAge = redis.HashGet<int>("user:2", "age");Console.WriteLine($"Hash User: {userName}, {userAge}");// 删除操作redis.Delete("name");// 检查键是否存在var exists = redis.Exists("user:1");Console.WriteLine($"user:1 exists: {exists}");// 获取所有键var allKeys = redis.GetAllKeys();Console.WriteLine($"All keys: {string.Join(", ", allKeys)}");// 存入缓存,设置过期时间为30分钟redis.Set($"user:3", user, TimeSpan.FromMinutes(30));// 清理过期项redis.RemoveExpiredItems();Console.ReadKey();}}
}

可以写个定时器定期清理过期项

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/884618.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Rust 力扣 - 54. 螺旋矩阵

文章目录 题目描述题解思路题解代码题目链接 题目描述 题解思路 我们只需要一圈一圈的从外向内遍历矩阵&#xff0c;每一圈遍历顺序为上边、右边、下边、左边 我们需要注意的是如果上边与下边重合或者是右边与左边重合&#xff0c;我们只需要遍历上边、右边即可 题解代码 i…

企业项目开发的流程

一.立项阶段 1.市场调研 了解市场需求和竞争对手情况。全面的市场调研分析报告。 用户调研&#xff1a;产品组针对目标用户进行定量和定性的调查&#xff0c;了解其需求和行为习惯&#xff0c;为产品的功能和设计方向提供依据。 举例&#xff1a;终端管家.用户分为商户和渠…

简化应用程序日志记录

什么是应用程序日志 应用程序日志是存储有关应用程序中发生的事件的信息的文件。应用程序日志包含以下信息&#xff1a; 用户活动&#xff0c;例如登录、注销、页面查看和搜索查询。应用程序错误&#xff0c;例如异常和崩溃。安全事件&#xff0c;例如登录尝试失败和可疑流量…

VR 创业之路:从《I Expect You To Die》到未来展望

今年是 Reality Labs 成立 10 周年&#xff0c;Meta 每周都会与不同的 XR 先驱进行交流&#xff0c;探讨他们在行业中的经历、经验教训以及对未来的展望。本次&#xff0c;他们与游戏设计师、作家兼 Schell Games CEO Jesse Schell 进行了深入交谈&#xff0c;了解了他的个人故…

【098】基于SpringBoot+Vue实现的垃圾分类系统

系统介绍 视频演示 基于SpringBootVue实现的垃圾分类系统 基于SpringBootVue实现的垃圾分类系统设计了三种角色、分别是管理员、垃圾分类管理员、用户&#xff0c;实现了个人中心、用户管理、垃圾分类管理员管理、垃圾分类管理、垃圾类型管理、垃圾图谱管理、系统管理等功能 …

C++和OpenGL实现3D游戏编程【连载17】——着色器进阶

欢迎来到zhooyu的专栏。 主页网址&#xff1a;【zhooyu】 专栏网址&#xff1a;【C和OpenGL实现3D游戏编程】 &#x1f31f;&#x1f31f;&#x1f31f;这里将通过一个OpenGL实现3D游戏编程实例教程&#xff0c;带大家深入学习OpenGL知识。知识无穷而人力有穷&#xff0c;希望…

前端技术月刊-2024.11

本月技术月刊聚焦于前端技术的最新发展和业务实践。业界资讯部分&#xff0c;React Native 0.76 版本发布&#xff0c;带来全新架构&#xff1b;Deno 2.0 和 Node.js 23 版本更新&#xff0c;推动 JavaScript 生态进步&#xff1b;Flutter 团队规模缩减&#xff0c;引发社区关注…

定制化视频生成新模范!零样本主体驱动,精确运动控制!复旦阿里等发布DreamVideo-2

文章链接&#xff1a;https://arxiv.org/pdf/2410.13830 项目链接&#xff1a;https://dreamvideo2.github.io/ 亮点直击 DreamVideo-2&#xff0c;首个无需微调&#xff0c;同时支持主体定制和运动控制的零样本视频定制框架&#xff0c;能够通过设计的参考注意力学习主体外观&…

mysql--多表查询

一、联合查询 作用&#xff1a;合并结果集就是把两个select语句的查询结果合并到一起&#xff01; 合并结果集有两种方式&#xff1a; UNION&#xff1a;合并并去除重复记录&#xff0c;例如&#xff1a;SELECT * FROM t1 UNION SELECT * FROM t2&#xff1b; UNION ALL&a…

PHP图书馆借阅管理系统-计算机毕业设计源码01649

基于HTML5CSS的图书馆借阅管理系统的设计与实现 摘 要 随着互联网大趋势的到来&#xff0c;社会的方方面面&#xff0c;各行各业都在考虑利用互联网作为媒介将自己的信息及时有效地推广出去&#xff0c;而其中最好的方式就是建立网络管理系统&#xff0c;并对其进行信息管理。本…

VMware系统镜像推荐网站

今天准备找一个Mac系统的镜像&#xff0c;在网上搜大部分都是广告&#xff0c;有的还做的很隐蔽&#xff0c;不点进去都无法确定&#xff0c;非常麻烦&#xff0c;不如多花点时间自己整理一个使用的网站。 如果有更优推荐&#xff0c;请在评论中说明&#xff0c;我会及时更新并…

vscode通过.vscode/launch.json 内置php服务启动thinkphp 应用后无法加载路由解决方法

我们在使用vscode的 .vscode/launch.json Launch built-in server and debug 启动thinkphp应用后默认是未加载thinkphp的路由文件的&#xff0c; 这个就导致了&#xff0c;某些thinkphp的一些url路由无法访问的情况&#xff0c; 如http://0.0.0.0:8000/api/auth.admin/info这…

中国90米土壤渗流因子Fsic数据

Fsic(土壤渗流因子)&#xff1a;土壤渗流因子的计算是根据美国农业部(USDA)土壤质地分类&#xff0c; 进行分类、赋值并归一化,得到土壤渗流因子Fsic的值。将13种土壤质地类型分别在0-1之间均等赋值得到。其中Fsic值越高&#xff0c;代表土壤渗水能力越强&#xff0c;Fsic值域范…

【大语言模型】ACL2024论文-03 MAGE: 现实环境下机器生成文本检测

【大语言模型】ACL2024论文-03 MAGE: 现实环境下机器生成文本检测 目录 文章目录 【大语言模型】ACL2024论文-03 MAGE: 现实环境下机器生成文本检测目录摘要研究背景问题与挑战如何解决核心创新点算法模型实验效果&#xff08;包含重要数据与结论&#xff09;主要参考工作后续优…

【Linux】centos7安装配置DHCP、FTP服务

文章目录 一、DHCP服务介绍1、DHCP服务器2、DHCP客户机3、工作流程 二、安装配置DHCP1、查询是否安装DHCP软件包2、安装3、配置DHCP4、修改配置信息5、重启 二、FTP服务1、安装并启动VSFTP服务2、安装vsftp客户端 一、DHCP服务介绍 DHCP服务主要功能是动态分配IP地址&#xff…

HTML 基础标签——链接标签 <a> 和 <iframe>

文章目录 1. `<a>` 标签属性详细说明示例2. `<iframe>` 标签属性详细说明示例注意事项总结链接标签在HTML中是实现网页导航的重要工具,允许用户从一个页面跳转到另一个页面或嵌入外部内容。主要的链接标签包括 <a> 标签和<iframe> 标签。本文将深入探…

Java日志脱敏(二)——fastjson Filter + 注解 + 工具类实现

背景简介 日志脱敏 是常见的安全需求&#xff0c;最近公司也需要将这一块内容进行推进。看了一圈网上的案例&#xff0c;很少有既轻量又好用的轮子可以让我直接使用。我一直是反对过度设计的&#xff0c;而同样我认为轮子就应该是可以让人拿去直接用的。所以我准备分享两篇博客…

Launcher3 去掉桌面搜索索框

文章目录 需求实现需求说明 参考资料修改文件实现思路首页显示的搜索框去除应用列表中的搜索框去除解决方案代码跟踪代码扩展 需求 Launcher3 去掉搜桌面索框 实现需求说明 每个平台平台源码有区别&#xff0c;比如&#xff1a;MTK、高通、展讯、RK、谷歌…单个平台下 不同A…

红队-shodan搜索引擎篇

如涉及侵权马上删除文章 笔记的只是方便各位师傅学习知识,以下网站只涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负 一.shodan原理与功能的介绍 Shodan Search Engine 它是专门搜网络设备的,只要联网的,只要有IP地址的都可以称为网络设备 1.shodan&#x…

初始JavaEE篇——多线程(5):生产者-消费者模型、阻塞队列

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a;JavaEE 文章目录 阻塞队列生产者—消费者模型生产者—消费者模型的优势&#xff1a;生产者—消费者模型的劣势&#xff1a; Java标准库中的阻…