MVC处理变通方法中的MemoryCache.Default

时间:2013-06-19 11:57:59

标签: asp.net asp.net-mvc caching memorycache

我正在努力实现解决此线程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系统上进行操作了。

更新 具体来说,我想知道我是如何实现推荐的解决方法。有人可以举例说明如何实现这一点吗?

2 个答案:

答案 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论坛上提到这一点。

Connect Issue

social.msdn

将轮询间隔增加30小时的配置设置:

<system.runtime.caching>
    <memoryCache>
        <namedCaches>
            <add name="Default"
                cacheMemoryLimitMegabytes="0"
                physicalMemoryLimitPercentage="0"
                pollingInterval="30:00:00" />
        </namedCaches>
    </memoryCache>
</system.runtime.caching>