VB.NET中MemoryCache跨页面无法读取缓存值的问题
问题分析与解决方案
你遇到的问题是ASP.NET Web Forms中使用System.Runtime.Caching.MemoryCache时跨页面无法读取缓存项,核心原因通常是MemoryCache与ASP.NET Web应用生命周期的适配问题,或者是进程/应用域隔离导致的缓存无法共享。以下是具体排查点和解决办法:
常见原因
- 应用程序池回收:如果写入缓存后应用程序池意外回收,缓存会被清空。这种情况在调试模式下或服务器内存不足时容易发生。
- 缓存组件适配问题:
MemoryCache是.NET通用缓存组件,适用于所有.NET应用场景,但在ASP.NET Web Forms中,它的生命周期与ASP.NET应用域的绑定不如专门的HttpRuntime.Cache紧密,可能出现缓存项被提前回收或无法跨页面共享的情况。 - 应用隔离:如果两个页面属于不同的虚拟目录或应用程序池,
MemoryCache的实例是进程隔离的,自然无法读取到对方的缓存。
解决办法
改用ASP.NET专用缓存HttpRuntime.Cache
在ASP.NET Web Forms场景下,推荐使用System.Web.Caching.Cache(通过HttpRuntime.Cache访问),它是专为Web应用设计的全局缓存,与ASP.NET应用域完全集成,跨页面共享更可靠。
修改后的第一个页面代码:
Dim myTestValue As String Dim myRetrievedValue As String Dim myMessage As String Dim myCacheKey As String = "myTestKey" ' 使用ASP.NET专用缓存 Dim myCache As System.Web.Caching.Cache = HttpRuntime.Cache If myCache(myCacheKey) Is Nothing Then ' 设置10分钟绝对过期 myTestValue = "ABCD" myCache.Insert(myCacheKey, myTestValue, Nothing, DateTime.Now.AddMinutes(10), TimeSpan.Zero) End If myRetrievedValue = myCache(myCacheKey) myMessage = If(myRetrievedValue Is Nothing, "Cache has failed.", "Cache has succeeded.")
修改后的第二个页面代码:
Dim myRetrievedValue As String Dim myMessage As String Dim myCacheKey As String = "myTestKey" Dim myCache As System.Web.Caching.Cache = HttpRuntime.Cache myRetrievedValue = myCache(myCacheKey) myMessage = If(myRetrievedValue Is Nothing, "Cache has failed.", "Cache has succeeded.")
排查验证步骤
- 确认应用归属:检查两个页面是否属于同一虚拟目录、同一应用程序池,不同应用的缓存是完全隔离的。
- 监控应用程序池状态:在
Global.asax中添加Application_End事件日志,确认跳转过程中应用程序池是否被回收:
Sub Application_End(ByVal sender As Object, ByVal e As EventArgs) ' 记录日志,比如写入文本文件 System.IO.File.AppendAllText(Server.MapPath("~/App_Data/app_end.log"), $"应用程序池回收:{DateTime.Now}{Environment.NewLine}") End Sub
- 缓存键验证:在两个页面中输出缓存的所有键,确认目标键是否存在:
' 输出所有缓存键 For Each key As String In myCache Debug.WriteLine($"缓存键:{key}") Next
内容的提问来源于stack exchange,提问作者Herman Badenhorst
相关产品推荐
相关产品推荐

