我正在努力实现解决此线程MemoryCache Empty : Returns null after being set中提到的缓存问题的解决方法。
我的最新尝试有以下代码来获取一个实例(按建议包装)在using语句中以禁止缓存被处理:
private static CacheDl _instance;
public static CacheDl Instance
{
get
{
if (_instance == null)
{
using (ExecutionContext.SuppressFlow())
{
_instance = new CacheDl();
}
}
return _instance;
}
}
private static ObjectCache Cache { get { return MemoryCache.Default; } }
当然这不起作用..我也尝试用类似的东西包装Cache'getter',但仍然没有交易。
我也试过指定一个大的pollingInterval来完全抑制行为但仍然没有成功。
private ObjectCache _cache;
private ObjectCache Cache
{
get
{
using (ExecutionContext.SuppressFlow())
{
return _cache ?? (_cache = new MemoryCache("my-cache", new NameValueCollection { { "pollingInterval", "30:00:00" } }));
}
}
}
你猜对了,没有运气。任何帮助将不胜感激。
顺便说一下,我已经提交了微软提到的Fixpack,但是在提交请求4小时后还没有回复任何内容。
老实说,我真的更喜欢将这些内容汇总到一个正式的Windows Update中,这样我们就不必在非.NET 4.5系统上进行操作了。
更新 具体来说,我想知道我是如何实现推荐的解决方法。有人可以举例说明如何实现这一点吗?
答案 0 :(得分:1)
我正在研究同样的问题。在我的情况下,问题似乎是缓存被放置在AppDomain的UnhandledException事件上。请参阅MemoryCache here的源代码段。
正如您所看到的,它处理自己。我的解决方案是将我的缓存访问包装在一个可以订阅此事件的类中,并在旧缓存被处理时初始化一个新缓存。这个解决方案似乎对我有用,但确实感觉相当黑客。
在UnhandledException事件中,仍然会意外清除缓存,但至少可以通过这种方式重新开始使用新缓存。
public class MyCacheWrapper
{
private MemoryCache cache;
public MyCacheWrapper()
{
cache = new MemoryCache("settings");
AppDomain.CurrentDomain.UnhandledException += (sender, args) =>
{
if(args.IsTerminating)
cache = new MemoryCache("settings");
};
}
}
另请注意,当您希望清除缓存时,也可以使用此类来处置和重新创建缓存,因为MemoryCache的Trim()方法无法正常工作。
答案 1 :(得分:0)
使用配置设置对此进行排序,以将Cache轮询间隔延长到足以使应用程序池在达到间隔之前回收。在构造一个Cache实例时尝试在代码中执行此操作但是没有用完..
对相关Connect问题的评论提到这是可行的黑客,如果你可以控制你的应用程序池,而另一个在social.msdn论坛上提到这一点。
将轮询间隔增加30小时的配置设置:
<system.runtime.caching>
<memoryCache>
<namedCaches>
<add name="Default"
cacheMemoryLimitMegabytes="0"
physicalMemoryLimitPercentage="0"
pollingInterval="30:00:00" />
</namedCaches>
</memoryCache>
</system.runtime.caching>