我有一个使用新的.NET 4 System.Runtime.Caching MemoryCache的MVC 3应用程序的问题.我注意到在看似无法预测的时间之后,它会停止缓存,并且表现得像空的一样.考虑一下我直接从ASP.NET MVC中的测试View获取的代码:
MemoryCache.Default.Set("myname","fred", new CacheItemPolicy() { SlidingExpiration = new TimeSpan(0,5,0) });
Response.Write(MemoryCache.Default["myname"]);
Run Code Online (Sandbox Code Playgroud)
当它工作时,可预测的"fred"被打印出来.但是,当问题开始出现时,尽管如此Set(),值为MemoryCache.Default["myname"]null.我可以通过在线上设置断点Response.Write()并使用立即窗口直接设置和读取缓存来证明这一点- 它不会设置它并保持为空!让它再次运行的唯一方法是使AppDomain回收.
有趣的是,当应用程序正常工作时,我可以通过打破Response.Write()线路并运行来激发问题MemoryCache.Default.Dispose().之后,MemoryCache.Default本身不为null(为什么会这样?),但不保存任何设置.它不会导致任何错误,但不会保存任何内容.
任何人都可以验证并解释吗?我相信我已经发现,当应用程序停止工作时,有些东西是Disposing MemoryCache.Default,但这不是我!
UPDATE
好吧,我现在厌倦了这个问题!CLRProfiler似乎不适用于MVC 3.SciTech的CLR工具很好 - RedGate ANTS也是如此.但他们告诉我的只是MemoryCache对象被某些东西处理掉了!我还证明了(通过时间戳打印)我的页面上应该被缓存的部分视图(由OutputCacheAttribute指定)在几分钟后停止缓存 - 它会在每次调用页面时开始刷新.为了澄清环境,我直接在运行Win 7 Ultimate的开发工作站上的IIS 7.5服务器上运行.上面提到的内存工具表明我在播放对象方面只使用了大约9mb的内存.
无奈之下,我已经改变了我的缓存代码,首先搜索环境HttpContext以挂钩并使用其缓存功能(如果有的话).早期测试显示这是可靠的,但感觉就像一个讨厌的黑客.
我觉得MemoryCache和OutputCache不能保证与MVC 3一起工作......
我已经比较了.NET 4.0中的system.runtime.caching和企业库缓存块的性能,令我惊讶的是,当从缓存项中获取大数据集时,它的表现非常糟糕.
Enterprise Library在大约0,15ms内获取100个对象,在大约0.25ms内获取10000个对象.这对于进程内缓存来说是快速且自然的,因为实际上不需要复制数据(仅引用).
.NET 4.0缓存在大约25毫秒内获取100个对象,在大约1500毫秒内获取10000个对象!相比之下这非常慢,这让我怀疑缓存是在进程外完成的.
我是否缺少一些配置选项,例如启用进程内缓存,还是企业库缓存块真的这么快?
更新
这是我的基准:
首先,我将数据从数据库加载到缓存(与基准分开).
我在get方法周围使用一个计时器来测量时间(以毫秒为单位):
EnterpriseLibrary缓存
Microsoft.Practices.EnterpriseLibrary.Caching.CacheManager _cache;
public void InitCache(){
_cache = CacheFactory.GetCacheManager("myCacheName");
}
public void Benchmark(){
HighPerformanceTimer timer = new HighPerformanceTimer();
timer.Start();
myObject o = (myObject)_cache.GetData(myCacheKey);
timer.Stop();
Response.Write(timer.GetAsStringInMilliseconds());
}
Run Code Online (Sandbox Code Playgroud)
.NET 4.0缓存
System.Runtime.Caching.MemoryCache _cache;
public void InitCache(){
_cache = new MemoryCache("myCacheName");
}
public void Benchmark(){
HighPerformanceTimer timer = new HighPerformanceTimer();
timer.Start();
myObject o = (myObject)_cache.Get(myCacheKey);
timer.Stop();
Response.Write(timer.GetAsStringInMilliseconds());
}
Run Code Online (Sandbox Code Playgroud)
基准测试执行1000次以计算获取对象的平均时间,以确保测试的可靠性.计时器是我使用的自定义计时器,任何计时器计数毫秒都应该这样做.
有趣的是,"myObject"有很多引用.如果涉及任何序列化,我就会理解为什么这个对象的性能不同(比如在分布式缓存中),但这些都是进程中的缓存,理论上应该可以在没有很多重大差异的情况下工作.
我听说.NET 4有一个新的缓存API.
好的,所以好的旧的System.Web.Caching.Cache(顺便说一下,仍然在.NET 4中)能够设置所谓的CacheDependency对象来确定缓存的项目是否过期.
还可以通过从中派生自定义子类来指定用于确定缓存项目是否仍然可用的自定义逻辑CacheDependency.
我很好奇,有没有办法在新的API中提供这样的逻辑?
我正在编写一个相当简单的Windows窗体工具来帮助我在数据库上执行某些操作.我经常需要去数据库获取ID,我无法取消获取ID.
我发现了一些引用它,比如这个,它们都建议我应该寻找System.Runtime.Caching,但是当我去Add Reference时,没有System.Runtime.Caching组件.
我在这里错过了什么吗?
.net ×4
.net-4.0 ×3
caching ×3
c# ×2
asp.net ×1
asp.net-mvc ×1
memorycache ×1
performance ×1
winforms ×1