C#实现简单的内存缓存

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

功能:

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

优点:

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

限制:

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

代码实现:

cs 复制代码
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();
        }
    }
}

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

相关推荐
向前看-3 小时前
验证码机制
前端·后端
岁月变迁呀3 小时前
Redis梳理
数据库·redis·缓存
黄油饼卷咖喱鸡就味增汤拌孜然羊肉炒饭4 小时前
SpringBoot如何实现缓存预热?
java·spring boot·spring·缓存·程序员
超爱吃士力架4 小时前
邀请逻辑
java·linux·后端
fantasy_arch5 小时前
CPU性能优化-磁盘空间和解析时间
网络·性能优化
Code apprenticeship5 小时前
怎么利用Redis实现延时队列?
数据库·redis·缓存
百度智能云技术站5 小时前
广告投放系统成本降低 70%+,基于 Redis 容量型数据库 PegaDB 的方案设计和业务实践
数据库·redis·oracle
装不满的克莱因瓶5 小时前
【Redis经典面试题六】Redis的持久化机制是怎样的?
java·数据库·redis·持久化·aof·rdb
AskHarries6 小时前
Spring Cloud OpenFeign快速入门demo
spring boot·后端
向宇it7 小时前
【从零开始入门unity游戏开发之——C#篇25】C#面向对象动态多态——virtual、override 和 base 关键字、抽象类和抽象方法
java·开发语言·unity·c#·游戏引擎