From ea1fc8a322ef0d2c1bc6c1253eebb757cd4a995f Mon Sep 17 00:00:00 2001 From: zpc Date: Sat, 9 Nov 2024 03:07:53 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B8=B8=E6=88=8F=E5=88=97=E8=A1=A8=E5=BC=82?= =?UTF-8?q?=E6=AD=A5=E5=AE=9E=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/GameController.cs | 4 +- .../Cache/CloudGamingCache.cs | 2 +- .../Cache/Special/GameEntityCache.cs | 196 ++++++++++-------- .../Code/CloudGaming.Code/Epg/EpgBLL.cs | 35 ++-- .../Code/CloudGaming.Code/Epg/EpgExtend.cs | 4 +- .../Code/CloudGaming.Code/Game/GameBLL.cs | 28 +-- .../MiddlewareExtend/RedisCacheMiddleware.cs | 2 +- .../CacheHelper/CommonDataEntityCache.cs | 127 +++++++++++- .../CacheHelper/MemoryCacheHelper.cs | 15 +- 9 files changed, 280 insertions(+), 133 deletions(-) diff --git a/src/CloudGaming/Api/CloudGaming.Api/Controllers/GameController.cs b/src/CloudGaming/Api/CloudGaming.Api/Controllers/GameController.cs index 798b456..da1988c 100644 --- a/src/CloudGaming/Api/CloudGaming.Api/Controllers/GameController.cs +++ b/src/CloudGaming/Api/CloudGaming.Api/Controllers/GameController.cs @@ -56,7 +56,7 @@ namespace CloudGaming.Api.Controllers /// [HttpGet] [RedisCache(2, 2, 0)] - public GameInfoDto GetGameInfo([FromQuery] string gameId) + public Task GetGameInfo([FromQuery] string gameId) { GameBLL gamebll = new GameBLL(this.ServiceProvider); return gamebll.GetGameInfo(gameId); @@ -68,7 +68,7 @@ namespace CloudGaming.Api.Controllers /// [HttpGet] [RedisCache(0, 5, 0)] - public List GameRecommendations([FromQuery] string? gameId) + public Task> GameRecommendations([FromQuery] string? gameId) { GameBLL gamebll = new GameBLL(this.ServiceProvider); diff --git a/src/CloudGaming/Code/CloudGaming.Code/Cache/CloudGamingCache.cs b/src/CloudGaming/Code/CloudGaming.Code/Cache/CloudGamingCache.cs index c95a720..0c7f3ca 100644 --- a/src/CloudGaming/Code/CloudGaming.Code/Cache/CloudGamingCache.cs +++ b/src/CloudGaming/Code/CloudGaming.Code/Cache/CloudGamingCache.cs @@ -95,7 +95,7 @@ namespace CloudGaming.Code.Cache get { - return GameEntityCache?.DataList ?? new List(); + return GameEntityCache?.DataListAsync.Result;// ?? new List(); } } diff --git a/src/CloudGaming/Code/CloudGaming.Code/Cache/Special/GameEntityCache.cs b/src/CloudGaming/Code/CloudGaming.Code/Cache/Special/GameEntityCache.cs index 53cbd72..456d5c4 100644 --- a/src/CloudGaming/Code/CloudGaming.Code/Cache/Special/GameEntityCache.cs +++ b/src/CloudGaming/Code/CloudGaming.Code/Cache/Special/GameEntityCache.cs @@ -10,6 +10,8 @@ using CloudGaming.GameModel.Db.Db_Game; using HuanMeng.DotNetCore.CacheHelper; using HuanMeng.DotNetCore.Redis; +using Microsoft.Extensions.Caching.Memory; + using Newtonsoft.Json; using Org.BouncyCastle.Utilities.Collections; @@ -24,37 +26,63 @@ namespace CloudGaming.Code.Cache.Special /// /// 游戏缓存表 /// - public class GameEntityCache(DAO dao, IDatabase database, IMapper mapper, AppConfig appConfig) : CommonDataEntityCache(GameEntityCache.GameEntityCacheLock, 60 * 60 * 24 * 7) + public class GameEntityCache(DAO dao, IDatabase database, IMapper mapper, AppConfig appConfig) : + CommonDataEntityCacheAsync(GameEntityCache.SemaphoreSlim, 60 * 60 * 24) + //CommonDataEntityCache(GameEntityCache.GameEntityCacheLock, 60 * 60 * 24 * 7) { - public static object GameEntityCacheLock; + /// + /// 异步锁 + /// + public static SemaphoreSlim SemaphoreSlim = new SemaphoreSlim(1, 1); + /// + /// 内存key + /// public override string key => $"{appConfig.Identifier}:game:gameInfo"; - + /// + /// 缓存锁key + /// public string locaKey => $"lock:gameInfo"; + /// + /// redis 缓存key + /// public string RedisKey => $"cache:game:gameInfo"; + /// + /// 缓存时间 + /// + public const int CacheHoursTime = 10; - public override List GetDataList() + + + /// + /// 游戏数据 + /// + /// + public override async Task> GetDataListAsync() { - var gameCbtList = dao.DaoPhone.Context.T_GameCBT.AsNoTracking().Where(it => it.IsOnline).ToList() ?? new List(); - var gameListDict = dao.DaoGame.Context.T_Game_List.AsNoTracking().ToDictionary(g => g.GameId); - var gameChildList = dao.DaoGame.Context.T_Game_ChildList.AsNoTracking().ToList(); - - var gameTypesDict = dao.DaoGame.Context.T_Game_Types.AsNoTracking().ToDictionary(type => type.TypeId); - var gameTagsDict = dao.DaoGame.Context.T_Game_Tags.AsNoTracking().ToDictionary(tag => tag.TagId); - //游戏分享头像 - var gameUserShare = dao.DaoGame.Context.T_Game_UserShare.AsNoTracking().GroupBy(it => it.GameId).ToDictionary(it => it.Key, it => it.Last().NickName); - var appConfig = dao.DaoExt.Context.T_App_Config.AsNoTracking().Where(it => it.ConfigType == 3).ToList(); + var gameCbtList = await dao.DaoPhone.Context.T_GameCBT.AsNoTracking().Where(it => it.IsOnline).ToListAsync() ?? new List(); + //游戏列表 + var gameListDict = await dao.DaoGame.Context.T_Game_List.AsNoTracking().ToDictionaryAsync(g => g.GameId); + //游戏标签、分类关联 + var gameChildList = await dao.DaoGame.Context.T_Game_ChildList.AsNoTracking().ToListAsync(); + //游戏分类 + var gameTypesDict = await dao.DaoGame.Context.T_Game_Types.AsNoTracking().ToDictionaryAsync(type => type.TypeId); + //标签 + var gameTagsDict = await dao.DaoGame.Context.T_Game_Tags.AsNoTracking().ToDictionaryAsync(tag => tag.TagId); + //游戏用户分享 + var gameUserShare = await dao.DaoGame.Context.T_Game_UserShare.AsNoTracking().GroupBy(it => it.GameId).ToDictionaryAsync(it => it.Key, it => it.Last().NickName); + //游戏配置 + var appConfig = await dao.DaoExt.Context.T_App_Config.AsNoTracking().Where(it => it.ConfigType == 3).ToListAsync(); + //统一消耗配置 var config = appConfig.GetAppConfig(3, 1, null); var defaultConsumeDiamondNumHour = 0; if (!string.IsNullOrEmpty(config?.ConfigValue)) { int.TryParse(config?.ConfigValue, out defaultConsumeDiamondNumHour); } - //var lorem = new Bogus.DataSets.Lorem(locale: "zh_CN"); + //生成用户昵称 var faker = new Faker("zh_CN"); - //f.r - - //lorem. + //组装游戏 var gameInfos = gameCbtList .Where(gameCbt => gameListDict.ContainsKey(gameCbt.GameId)) .Select(gameCbt => @@ -76,7 +104,6 @@ namespace CloudGaming.Code.Cache.Special gameInfo.ConsumeDiamondNumHour = defaultConsumeDiamondNumHour; } - if (gameInfo.ConsumeDiamondNumHour > 0) { gameInfo.GameDetailsofCharges = $"游戏资费:游玩按分钟计费,{gameInfo.ConsumeDiamondNumHour}钻石/小时。"; @@ -92,85 +119,93 @@ namespace CloudGaming.Code.Cache.Special return gameInfos; } - /// - /// - /// - public override List DataList + + public override Task> DataListAsync { get { - start: - if (_dataList != null) return _dataList; + if (_dataList != null) return Task.FromResult(_dataList); + var tempDataList = MemoryCacheHelper.GetCache>(key); if (tempDataList != null) { _dataList = tempDataList; - return _dataList; + return Task.FromResult(_dataList); } - - long hashLength = database.HashLength(RedisKey); - if (hashLength > 0) + return Task.Run(async () => { - var hashEntries = database.HashGetAll(RedisKey); - var list = hashEntries - .Where(entry => !string.IsNullOrEmpty(entry.Value)) - .Select(entry => JsonConvert.DeserializeObject(entry.Value)) - .ToList(); + start: + long hashLength = await database.HashLengthAsync(RedisKey); + if (hashLength > 0) + { + var hashEntries = await database.HashGetAllAsync(RedisKey); + var list = hashEntries + .Where(entry => !string.IsNullOrEmpty(entry.Value)) + .Select(entry => JsonConvert.DeserializeObject(entry.Value)) + .ToList(); - MemoryCacheHelper.SetCache(key, list, 10); - _dataList = list; + MemoryCacheHelper.SetCache(key, list, TimeSpan.FromHours(CacheHoursTime)); + _dataList = list; + return _dataList; + } + + if (!database.StringSetLock(locaKey, "1", 5)) + { + await Task.Delay(50); + goto start; + } + + try + { + tempDataList ??= await GetDataListAsync(); + MemoryCacheHelper.SetCache(key, tempDataList, TimeSpan.FromHours(CacheHoursTime)); + var serializedGameInfos = tempDataList + .Select(info => new HashEntry($"gameInfo:{info.GameId}", JsonConvert.SerializeObject(info))) + .ToArray(); + await database.HashSetAsync(RedisKey, serializedGameInfos); + // 设置过期时间为1天 + await database.KeyExpireAsync(RedisKey, TimeSpan.FromDays(1)); + _dataList = tempDataList; + } + finally + { + database.KeyDelete(locaKey); + } return _dataList; - } + }); - if (!database.StringSetLock(locaKey, "1", 5)) - { - goto start; - } - tempDataList ??= GetDataList(); - var serializedGameInfos = tempDataList - .Select(info => new HashEntry($"gameInfo:{info.GameId}", JsonConvert.SerializeObject(info))) - .ToArray(); - database.HashSet(RedisKey, serializedGameInfos); - - MemoryCacheHelper.SetCache(key, tempDataList, 60 * 60); - _dataList = tempDataList; - database.KeyDelete(locaKey); - return _dataList; } } - //public Task> DataListAsync - //{ - // get - // { - // return new List(); - // } - //} private Dictionary gameInfoDic; + + /// /// 游戏详情 /// - public Dictionary GameInfoDic + public Task> GameInfoAsync { get { - if (gameInfoDic == null) + if (gameInfoDic != null) { - gameInfoDic = DataList.ToDictionary(it => it.GameId); + return Task.FromResult(gameInfoDic); } - return gameInfoDic; + return Task.Run(async () => { gameInfoDic = (await DataListAsync).ToDictionary(it => it.GameId); return gameInfoDic; }); } } + + /// /// 获取游戏详情 /// /// /// - public GameInfo? this[string? gameId] + public Task this[string? gameId] { get { @@ -178,15 +213,11 @@ namespace CloudGaming.Code.Cache.Special { return null; } - return GameInfoDic[gameId] ?? null; + return Task.Run(async () => (await GameInfoAsync)[gameId] ?? null); } } - private List GetGameExtendedAttributes( - List gameChildList, - string gameId, - int childType, - Dictionary dictionary) where T : class + private List GetGameExtendedAttributes(List gameChildList, string gameId, int childType, Dictionary dictionary) where T : class { return gameChildList .Where(it => it.GameId == gameId && it.ChildType == childType && (it.ChildId ?? 0) > 0) @@ -217,25 +248,26 @@ namespace CloudGaming.Code.Cache.Special public override bool ClearData() { - lock (GameEntityCacheLock) - { - database.KeyDelete(key); - MemoryCacheHelper.DelCache(key); - _dataList = null; - gameInfoDic = null; - } + + database.KeyDelete(key); + MemoryCacheHelper.DelCache(key); + database.KeyDelete(RedisKey); + _dataList = null; + gameInfoDic = null; + return true; } public override void ReloadData() { - lock (lockObj) - { - database.KeyDelete(key); - MemoryCacheHelper.DelCache(key); - _dataList = null; - var x = DataList; - } + database.KeyDelete(key); + database.KeyDelete(RedisKey); + + MemoryCacheHelper.DelCache(key); + + _dataList = null; + var x = DataListAsync.Result; } + } } diff --git a/src/CloudGaming/Code/CloudGaming.Code/Epg/EpgBLL.cs b/src/CloudGaming/Code/CloudGaming.Code/Epg/EpgBLL.cs index dcd8d67..ba693c1 100644 --- a/src/CloudGaming/Code/CloudGaming.Code/Epg/EpgBLL.cs +++ b/src/CloudGaming/Code/CloudGaming.Code/Epg/EpgBLL.cs @@ -26,39 +26,33 @@ namespace CloudGaming.Code.Epg public async Task> GetHomeInfo() { var listQueryable = GetEpgCategory(EpgEnum.EpgCatIdName.大厅首页).AsQueryable(); - if (IsChecking) - { - listQueryable = listQueryable.Where(it => it.ShowStatus == 0 || it.ShowStatus == 2).AsQueryable(); - } - else - { - listQueryable = listQueryable.Where(it => it.ShowStatus == 0 || it.ShowStatus == 1).AsQueryable(); - } - var list = listQueryable.OrderBy(it => it.OrderId).ToList(); + int[] showStatus = IsChecking ? [0, 2] : [0, 1]; + var list = listQueryable.Where(it => showStatus.Contains(it.ShowStatus)).OrderBy(it => it.OrderId).ToList(); List epgCategoryDtos = new List(); - list.ForEach(it => + foreach (var it in list) { - var list = new List() + var epglist = new List() { //STEAMCLOUD }; var epgList = GetEpgList(it.Id); - epgList?.ForEach(item => + foreach (var item in epgList) { //如果首页展示数量小于集合数量,则退出 - if (it.ShowNumIndex < list.Count) + if (it.ShowNumIndex < epglist.Count) { - return; + break; } - var epgInfo = item.ToEpgInfo(Cache.GameEntityCache); + var epgInfo = await item.ToEpgInfo(Cache.GameEntityCache); if (epgInfo != null) { - list.Add(epgInfo); + epglist.Add(epgInfo); } - }); + } - if (list.Count > 0) + + if (epglist.Count > 0) { EpgCategoryDto epgCategoryDto = new EpgCategoryDto() { @@ -66,12 +60,13 @@ namespace CloudGaming.Code.Epg CategoryType = it.IdName, IsQuickStartPopUp = it.IsQuickStartPopUp ?? false, ShowNum_Index = it.ShowNumIndex ?? 0, - EpgList = list + EpgList = epglist }; epgCategoryDtos.Add(epgCategoryDto); } - }); + } + return epgCategoryDtos; } /// diff --git a/src/CloudGaming/Code/CloudGaming.Code/Epg/EpgExtend.cs b/src/CloudGaming/Code/CloudGaming.Code/Epg/EpgExtend.cs index b0f5875..2e15106 100644 --- a/src/CloudGaming/Code/CloudGaming.Code/Epg/EpgExtend.cs +++ b/src/CloudGaming/Code/CloudGaming.Code/Epg/EpgExtend.cs @@ -20,7 +20,7 @@ namespace CloudGaming.Code.Epg /// /// /// - public static EpgInfo ToEpgInfo(this T_Epg_Cfg epgCfg, GameEntityCache gameEntityCache) + public static async Task ToEpgInfo(this T_Epg_Cfg epgCfg, GameEntityCache gameEntityCache) { if (epgCfg.ResType == (int)EpgEnum.EpgResType.游戏 && string.IsNullOrEmpty(epgCfg.ResId)) { @@ -41,7 +41,7 @@ namespace CloudGaming.Code.Epg if (epgCfg.ResType == (int)EpgEnum.EpgResType.游戏) { - var gameInfo = gameEntityCache[epgCfg.ResId]; + var gameInfo = await gameEntityCache[epgCfg.ResId]; if (gameInfo == null) { return null; diff --git a/src/CloudGaming/Code/CloudGaming.Code/Game/GameBLL.cs b/src/CloudGaming/Code/CloudGaming.Code/Game/GameBLL.cs index 4ccb75f..ca53080 100644 --- a/src/CloudGaming/Code/CloudGaming.Code/Game/GameBLL.cs +++ b/src/CloudGaming/Code/CloudGaming.Code/Game/GameBLL.cs @@ -24,10 +24,8 @@ namespace CloudGaming.Code.Game /// public async Task> GetGameTypeListAsync() { - var gameList = Cache.GameEntityCache?.DataList ?? new List(); - var gameTypes = await Task.Run(() => - { - return CloudGamingCacheExtend.GetDataEntityCache(this, it => it.IsOnline)?.DataList + var gameList = await Cache.GameEntityCache.DataListAsync; + var list = CloudGamingCacheExtend.GetDataEntityCache(this, it => it.IsOnline)?.DataList .Where(it => gameList.Any(item => item.GameType?.Any(gameType => gameType.Id == it.TypeId) ?? false)) .OrderBy(it => it.OrderId) .Select(it => new GameExtendedAttribute @@ -37,9 +35,9 @@ namespace CloudGaming.Code.Game OrderId = it.OrderId }) .ToList(); - }); + return list; + - return gameTypes; } /// @@ -49,14 +47,8 @@ namespace CloudGaming.Code.Game /// public async Task> GetGameListAsync(int typeId) { - - var gameListDto = await Task.Run(() => - { - var gameList = Cache.GameEntityCache?.DataList ?? new List(); - var x = gameList.Where(it => it.GameType?.Any(item => item.Id == typeId) ?? false).Select(it => new - GameListDto(it)).ToList(); - return x; - }); + var gameList = await Cache.GameEntityCache.DataListAsync; + var gameListDto = gameList.Where(it => it.GameType?.Any(item => item.Id == typeId) ?? false).Select(it => new GameListDto(it)).ToList(); return gameListDto; } @@ -65,13 +57,13 @@ namespace CloudGaming.Code.Game /// /// /// - public GameInfoDto GetGameInfo(string gameId) + public async Task GetGameInfo(string gameId) { if (string.IsNullOrEmpty(gameId)) { return null; } - var game = Cache.GameEntityCache[gameId]; + var game = await Cache.GameEntityCache[gameId]; if (game == null) { return null; @@ -85,12 +77,12 @@ namespace CloudGaming.Code.Game /// /// /// - public List GameRecommendations(string gameId) + public async Task> GameRecommendations(string gameId) { List? gameInfos = null; if (!string.IsNullOrEmpty(gameId)) { - var game = Cache.GameEntityCache[gameId]; + var game = await Cache.GameEntityCache[gameId]; if (game != null) { var gameTagIds = game.GameTags.Select(it => it.Id); diff --git a/src/CloudGaming/Code/CloudGaming.Code/MiddlewareExtend/RedisCacheMiddleware.cs b/src/CloudGaming/Code/CloudGaming.Code/MiddlewareExtend/RedisCacheMiddleware.cs index fb1080d..4f68943 100644 --- a/src/CloudGaming/Code/CloudGaming.Code/MiddlewareExtend/RedisCacheMiddleware.cs +++ b/src/CloudGaming/Code/CloudGaming.Code/MiddlewareExtend/RedisCacheMiddleware.cs @@ -32,7 +32,7 @@ namespace CloudGaming.Code.MiddlewareExtend { // 检查当前请求是否需要缓存 var cacheAttribute = GetCacheAttribute(context); - if (cacheAttribute == null) + if (cacheAttribute == null || true) { await _next(context); return; diff --git a/src/CloudGaming/Utile/HuanMeng.DotNetCore/CacheHelper/CommonDataEntityCache.cs b/src/CloudGaming/Utile/HuanMeng.DotNetCore/CacheHelper/CommonDataEntityCache.cs index 84e9f9c..704ac56 100644 --- a/src/CloudGaming/Utile/HuanMeng.DotNetCore/CacheHelper/CommonDataEntityCache.cs +++ b/src/CloudGaming/Utile/HuanMeng.DotNetCore/CacheHelper/CommonDataEntityCache.cs @@ -1,11 +1,14 @@ using HuanMeng.DotNetCore.CacheHelper.Contract; +using Microsoft.EntityFrameworkCore.Metadata.Internal; + using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace HuanMeng.DotNetCore.CacheHelper @@ -55,12 +58,8 @@ namespace HuanMeng.DotNetCore.CacheHelper { lock (lockObj) { - tempDataList = MemoryCacheHelper.GetCache>(key); - if (tempDataList == null) - { - tempDataList = GetDataList(); - MemoryCacheHelper.SetCache(key, tempDataList, cacheTime); - } + tempDataList = GetDataList(); + MemoryCacheHelper.SetCache(key, tempDataList, cacheTime); } } _dataList = JsonConvert.DeserializeObject>(JsonConvert.SerializeObject(tempDataList)); @@ -95,4 +94,120 @@ namespace HuanMeng.DotNetCore.CacheHelper } } } + + /// + /// 异步缓存 + /// + /// + public abstract class CommonDataEntityCacheAsync : ICacheClearData, ICacheReloadData where T : class + { + + /// + /// 过期时间 + /// + protected int cacheTime; + + private readonly SemaphoreSlim _semaphore; // 异步锁 + + /// + /// + /// + /// 异步锁new SemaphoreSlim(initialCount: 1, maxCount: 1); + /// + protected CommonDataEntityCacheAsync(SemaphoreSlim semaphore, int cacheTime = 36000) + { + //new SemaphoreSlim(initialCount: 1, maxCount: 1); + this._semaphore = semaphore; + this.cacheTime = cacheTime; + } + + + /// + /// + /// + public abstract string key { get; } + + /// + /// 缓存数据 + /// + protected List? _dataList; + + + + /// + /// 数据 + /// + public virtual Task> DataListAsync + { + get + { + // 如果已有缓存数据,直接返回 + if (_dataList != null) + { + return Task.FromResult(_dataList); + } + + // 尝试从缓存获取 + var tempDataList = MemoryCacheHelper.GetCache>(key); + if (tempDataList != null) + { + _dataList = JsonConvert.DeserializeObject>(JsonConvert.SerializeObject(tempDataList)) ?? new List(); + return Task.FromResult(_dataList); + } + return Task.Run(async () => + { + // 进行异步加锁,避免多线程竞争 + await _semaphore.WaitAsync(); + try + { + // 重新检查缓存 + tempDataList = MemoryCacheHelper.GetCache>(key); + if (tempDataList == null) + { + tempDataList = await GetDataListAsync(); // 异步获取数据 + MemoryCacheHelper.SetCache(key, tempDataList, cacheTime); + } + _dataList = JsonConvert.DeserializeObject>(JsonConvert.SerializeObject(tempDataList)) ?? new List(); + + return _dataList; + } + finally + { + _semaphore.Release(); // 释放锁 + } + }); + } + } + + + + /// + /// 获取缓存数据 + /// + public abstract Task> GetDataListAsync(); + + /// + /// 清除缓存 + /// + /// + public virtual bool ClearData() + { + + MemoryCacheHelper.DelCache(key); + _dataList = null; + return true; + } + + /// + /// 重新加载缓存 + /// + public virtual void ReloadData() + { + + var tempDataList = GetDataListAsync().Result; + MemoryCacheHelper.SetCache(key, tempDataList, cacheTime); + _dataList = tempDataList; + + } + } } diff --git a/src/CloudGaming/Utile/HuanMeng.DotNetCore/CacheHelper/MemoryCacheHelper.cs b/src/CloudGaming/Utile/HuanMeng.DotNetCore/CacheHelper/MemoryCacheHelper.cs index 682fdbf..c631e35 100644 --- a/src/CloudGaming/Utile/HuanMeng.DotNetCore/CacheHelper/MemoryCacheHelper.cs +++ b/src/CloudGaming/Utile/HuanMeng.DotNetCore/CacheHelper/MemoryCacheHelper.cs @@ -1,4 +1,5 @@ using Microsoft.Extensions.Caching.Memory; + using System; using System.Collections.Generic; using System.Linq; @@ -22,7 +23,7 @@ namespace HuanMeng.DotNetCore.CacheHelper /// public static T? GetCache(string cacheName) where T : class, new() { - + return cache.TryGetValue(cacheName, out var value) ? value as T : null; } @@ -40,6 +41,18 @@ namespace HuanMeng.DotNetCore.CacheHelper cache.Set(cacheName, val, TimeSpan.FromSeconds(cacheTime)); } + /// + /// 设置缓存 + /// + /// + /// + /// 单位秒,默认1小时 + public static void SetCache(string cacheName, object val, TimeSpan timeSpan) + { + cache.Set(cacheName, val, timeSpan); + } + + /// /// 删除缓存 ///