控制台应用中HttpContext缓存自动清除,如何阻止缓存被清理?
问题分析
你遇到的缓存自动清除问题,核心原因是ASP.NET的HttpContext.Cache(底层是System.Web.Caching.Cache)默认的缓存策略导致的:
- 这是内存级缓存,完全绑定应用程序池的生命周期。当应用池因内存不足、定时回收或配置变更重启时,所有缓存都会被清空。
- 默认插入缓存时未指定过期规则和优先级,系统会通过LRU(最近最少使用)算法在内存紧张时自动回收优先级低的缓存项,这就是你2-3小时后缓存消失的直接原因。
解决方案
要阻止缓存被自动回收(除了应用池重启的极端情况),你需要在插入缓存时明确指定永不过期规则和最高优先级,同时修正代码里的小bug。
1. 修改缓存插入逻辑
使用Cache.Insert的重载方法,明确设置以下关键参数:
- 绝对过期时间设为
DateTime.MaxValue(永不过期) - 禁用滑动过期
- 设置缓存优先级为
CacheItemPriority.NotRemovable(不会被内存回收机制移除)
2. 修正CompleteList属性实现
调整属性的getter和setter,确保缓存插入时应用完整策略:
private List<Model.CacheModel> _CompleteList = null; public List<Model.CacheModel> CompleteList { get { if (_CompleteList == null) { _CompleteList = HttpContext.Current.Cache["CompleteList"] as List<Model.CacheModel>; if (_CompleteList == null) { _CompleteList = new List<Model.CacheModel>(); // 插入缓存时指定完整策略 HttpContext.Current.Cache.Insert( "CompleteList", _CompleteList, null, // 无缓存依赖项 DateTime.MaxValue, // 绝对永不过期 Cache.NoSlidingExpiration, // 禁用滑动过期 CacheItemPriority.NotRemovable, // 禁止被内存回收移除 null // 缓存移除回调,可选 ); } } return _CompleteList; } set { _CompleteList = value; // 更新缓存时同样应用完整策略 HttpContext.Current.Cache.Insert( "CompleteList", _CompleteList, null, DateTime.MaxValue, Cache.NoSlidingExpiration, CacheItemPriority.NotRemovable, null ); } }
3. 修正GetControl方法的缓存赋值逻辑
不要直接用Cache["Key"] = Value的简易方式赋值,同样使用带参数的Insert方法确保缓存策略生效:
public void GetControl(List<Model.CacheModel> List) { var CahcedList = HttpContext.Current.Cache["CompleteList"] as List<Model.CacheModel>; if (CahcedList == null) { // 替换直接赋值为带策略的Insert方法 HttpContext.Current.Cache.Insert( "CompleteList", List, null, DateTime.MaxValue, Cache.NoSlidingExpiration, CacheItemPriority.NotRemovable, null ); } else { if (CahcedList.LastOrDefault()?.Time != List.LastOrDefault()?.Time) { CahcedList.Remove(CahcedList.FirstOrDefault()); CahcedList.Add(List.LastOrDefault()); Clients.Others.broadcastAll(JsonConvert.SerializeObject(List.LastOrDefault())); } } }
额外提示
- 如果你的应用池配置了定时回收(比如默认的29小时自动回收),即使设置了上述参数,缓存还是会在应用池重启时被清空。这种场景下,建议使用分布式缓存(如Redis)来持久化缓存数据,完全脱离应用进程生命周期的限制。
- 如果是纯控制台应用,更推荐使用
System.Runtime.Caching.MemoryCache(.NET Framework/.NET Core通用),它比HttpContext.Cache更适配非Web环境,且同样支持设置过期规则和优先级。
内容的提问来源于stack exchange,提问作者adam johanson
相关产品推荐
相关产品推荐

