2

我很难解决此线程MemoryCache Empty 中提到的处置 Cache 问题的解决方法:在设置后返回 null

我最近的尝试有以下代码来获取一个实例,按照建议包装,在 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; } }

当然这不起作用..我也尝试将缓存“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" } }));
        }
    }
}

你猜对了,没有运气。任何帮助将不胜感激。

顺便说一句,我已经向 Microsoft 请求了提到的 Fixpack,但在提交请求 4 小时后还没有收到任何回复。

老实说,我真的更希望将其汇总到官方的 Windows 更新中,这样我们就不必费力地让它在非 .NET 4.5 系统上运行。

更新: 具体来说,我想知道我打算如何实施推荐的解决方法。有人可以举例说明如何实施吗?

4

2 回答 2

1

我正在解决同样的问题。在我的情况下,问题似乎是缓存设置在 AppDomain 的 UnhandledException 事件上。在此处查看 MemoryCache 的源代码片段。

如您所见,它自行处理。我的解决方案是将我的缓存访问包装在一个可以订阅此事件的类中,并在旧缓存被处置时初始化一个新缓存。该解决方案似乎对我有用,但确实感觉很hack-y。

缓存仍然会在 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() 方法无法正常工作。

于 2013-06-24T17:40:28.237 回答
0

最后用配置设置来解决这个问题,以延长缓存轮询间隔,足以让应用程序池在达到间隔之前回收。在构建 Cache 实例时尝试在代码中执行此操作,但没有成功。

如果您可以控制您的应用程序池,则有关 Connect 问题的评论提到这是可行的 hack,而另一条在 social.msdn 论坛上提到了这一点。

连接问题

社交.msdn

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

<system.runtime.caching>
    <memoryCache>
        <namedCaches>
            <add name="Default"
                cacheMemoryLimitMegabytes="0"
                physicalMemoryLimitPercentage="0"
                pollingInterval="30:00:00" />
        </namedCaches>
    </memoryCache>
</system.runtime.caching>
于 2013-07-02T07:17:44.283 回答