一、安装第三方库
二、官网
StackExchange.Redis |通用型 redis 客户端
三、连接示例
private static string redisConnectionString = "localhost:6379,password=yourpassword,defaultDatabase=0,allowAdmin=true,asyncTimeout=10000";private static string redisConnectionString = "localhost:6379,defaultDatabase=0,allowAdmin=true,asyncTimeout=10000";
四、封装:增删改查
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;namespace ConsoleApp2
{public class RedisData{/// <summary>/// 键(包含冒号前的内容)/// </summary>public string Key { get; set; }/// <summary>/// 键尾/// </summary>public string KeyTail { get; set; }/// <summary>/// 值/// </summary>public string Value { get; set; }/// <summary>/// 剩余过期时间(天)/// </summary>public int? TTLDays { get; set; }/// <summary>/// 剩余过期时间(分钟)/// </summary>public int? TTLMins { get; set; }/// <summary>/// 剩余过期时间(秒)/// </summary>public int? TTLSecs { get; set; }/// <summary>/// 到期时间/// </summary>public DateTime? ExpirationTime { get; set; }/// <summary>/// 查询时间/// </summary>public DateTime QueryTime { get; set; }}public static class RedisExtension{// 默认的 Redis 连接字符串private static string redisConnectionString = "localhost:6379,defaultDatabase=0,allowAdmin=true,asyncTimeout=10000";// 使用 Lazy 实例化连接,只会在第一次使用时连接 Redisprivate static Lazy<ConnectionMultiplexer> redis = new Lazy<ConnectionMultiplexer>(() => ConnectionMultiplexer.Connect(redisConnectionString));// 通过连接获取 Redis 数据库private static IDatabase db => redis.Value.GetDatabase();/// <summary>/// 尝试连接/// </summary>/// <param name="conn"></param>/// <returns></returns>public static async Task<bool> TryConnectAsync(string conn = null){// 如果传入了新的连接字符串,更新 Redis 连接if (!string.IsNullOrWhiteSpace(conn)){redisConnectionString = conn;// 清理现有连接,强制重新连接redis = new Lazy<ConnectionMultiplexer>(() => ConnectionMultiplexer.Connect(redisConnectionString));}try{// 通过插入 测试 Redis 连接string testKey = Guid.NewGuid().ToString();await InsertAsync(testKey, testKey);await DeleteAsync(testKey);return true; // 连接成功}catch (Exception ex){return false; // 连接失败}}/// <summary>/// 【增加】设置一个键值对/// </summary>/// <param name="key">第一个入参示例“NewYork:School:John”(文件夹形式);第三个入参可以传递形如TimeSpan.FromSeconds(30),传null则表明永不过期</param>/// <param name="value"></param>/// <param name="expiration"></param>public static async Task<bool> InsertAsync(string key, string value, TimeSpan? expiration = null){if (await GetRedisDataByKeyAsync(key) != null){return false;}if (await db.KeyExistsAsync(key)){return false;}if (expiration == null) // 不设置超时时间{await db.StringSetAsync(key, value);}else // 设置超时时间{await db.StringSetAsync(key, value, expiration);}return true;}/// <summary>/// 【更新】设置一个键值对/// </summary>/// <param name="key">第一个入参示例“NewYork:School:John”(文件夹形式);第三个入参可以传递形如TimeSpan.FromSeconds(30),传null则表明永不过期</param>/// <param name="value"></param>/// <param name="expiration"></param>public static async Task<bool> UpdateAsync(string key, string value, TimeSpan? expiration = null){if (await GetRedisDataByKeyAsync(key) == null){return false;}if (expiration == null) // 不设置超时时间{await db.StringSetAsync(key, value);}else // 设置超时时间{await db.StringSetAsync(key, value, expiration);}return true;}/// <summary>/// 【查询】键值对信息/// </summary>/// <param name="key"></param>/// <returns></returns>public static async Task<RedisData> GetRedisDataByKeyAsync(string key){if (await db.KeyExistsAsync(key)) // 键存在{RedisData data = new RedisData(){Key = key,Value = await db.StringGetAsync(key),KeyTail = key.Split(':').LastOrDefault(),QueryTime = DateTime.Now};var ttl = await db.KeyTimeToLiveAsync(key);if (ttl != null){data.ExpirationTime = DateTime.Now.Add(ttl.Value);data.TTLDays = Convert.ToInt32(ttl.Value.TotalDays);data.TTLMins = Convert.ToInt32(ttl.Value.TotalMinutes);data.TTLSecs = Convert.ToInt32(ttl.Value.TotalSeconds);}return data;}return null;}/// <summary>/// 【删除】指定键,只有在键存在时才删除/// </summary>/// <param name="key"></param>/// <returns></returns>public static async Task<bool> DeleteAsync(string key){if (await db.KeyExistsAsync(key)) // 判断键是否存在{return await db.KeyDeleteAsync(key); // 如果存在,删除键}return false; // 如果键不存在,返回 false}/// <summary>/// 【自定义指令(仅支持简单的)】/// </summary>/// 示例输入:PING INFO(查看配置信息) FLUSHDB(删除当前数据库所有键值对) FLUSHALL(删除所有数据库键值对)/// <returns></returns>public static async Task<string> SendCommandAsync(string command){string result = "";try{result = (await db.ExecuteAsync(command)).ToString();return result; // 返回响应}catch (Exception ex){return ex.Message.ToString();}}/// <summary>/// 【获取INFO配置信息】/// </summary>/// <returns></returns>public static async Task<Dictionary<string, string>> GetInfo(){var splitlabel = ":";var infos = await SendCommandAsync("INFO");var infosList = infos.Split().Where(x => x.Contains(splitlabel));var showdict = new Dictionary<string, string>();foreach (var item in infosList){var key = item.Split(splitlabel)[0].Trim();var value = item.Split(splitlabel)[1].Trim();switch (key){case "redis_version":showdict["版本号"] = value;break;case "redis_mode":showdict["模式"] = value;break;case "role":showdict["角色"] = value;break;case "process_id":showdict["进程PID"] = value;break;case "tcp_port":showdict["TCP端口"] = value;break;case "uptime_in_days":showdict["服务已运行天数"] = value;break;case "hz":showdict["每秒执行操作数"] = value;break;case "executable":showdict["执行文件路径"] = value;break;case "config_file":showdict["配置文件路径"] = value;//executablebreak;case "connected_clients":showdict["当前连接数"] = value;break;case "blocked_clients":showdict["阻塞数量"] = value;break;case "used_memory_human":showdict["总使用内存"] = value;break;case "used_memory_rss_human":showdict["物理内存"] = value;break;case "used_memory_peak_human":showdict["峰值使用内存"] = value;break;case "maxmemory_policy":showdict["内存回收策略"] = value;break;case "mem_fragmentation_ratio":showdict["碎片比例"] = value;break;case "mem_allocator":showdict["内存分配器"] = value;break;case "rdb_last_save_time":showdict["RDB上次成功保存的时间"] = DateTimeOffset.FromUnixTimeSeconds(Convert.ToInt32(value)).LocalDateTime.ToString("yyyy年MM月dd日 HH时mm分ss秒"); break;case "rdb_last_bgsave_status":showdict["RDB上次保存的状态"] = value;break;case "aof_enabled":showdict["是否启用 AOF 持久化"] = value;break;case "expired_keys":showdict["过期的键数量"] = value;break;case "pubsub_channels":showdict["当前的订阅频道数"] = value;break;case "pubsub_patterns":showdict["当前的订阅模式数"] = value;break;case "latest_fork_usec":showdict["最近一次 fork 操作的耗时(秒)"] = Math.Round(Convert.ToDouble(value)/1000,2).ToString();break;case "cluster_enabled":showdict["是否启用集群模式"] = value;break;default:break;}}return showdict;}}}