Asp.net I';当系统内存不足时,我试图处理一个对象-有没有更好的方法?

Asp.net I';当系统内存不足时,我试图处理一个对象-有没有更好的方法?,asp.net,caching,Asp.net,Caching,我目前正在做的是将一个项目添加到缓存中,并在从缓存中删除该对象时处理该对象。逻辑是,当内存消耗过高时,它会被删除。我愿意接受她的建议,但我希望尽量避免创建线程,而不是持续测量内存统计数据。这是我的密码: public class WebServiceCache : ConcurrentDictionary<string, WebServiceCacheObject>, IDisposable { private WebServiceCache() {

我目前正在做的是将一个项目添加到缓存中,并在从缓存中删除该对象时处理该对象。逻辑是,当内存消耗过高时,它会被删除。我愿意接受她的建议,但我希望尽量避免创建线程,而不是持续测量内存统计数据。这是我的密码:

public class WebServiceCache : ConcurrentDictionary<string, WebServiceCacheObject>, IDisposable
{
    private WebServiceCache()
    {
        if (HttpContext.Current != null && HttpContext.Current.Cache != null)
        {
            HttpContext.Current.Cache.Add("CacheTest", true, null, DateTime.Now.AddYears(1), System.Web.Caching.Cache.NoSlidingExpiration, 
                System.Web.Caching.CacheItemPriority.Low, 
                (key, obj, reason) => {
                    if (reason != System.Web.Caching.CacheItemRemovedReason.Removed)
                    {
                        WebServiceCache.Current.ClearCache(50);
                    }
                });
        }
    }

    private static WebServiceCache _current;
    public static WebServiceCache Current
    {
        get
        {
            if (_current != null && _current.IsDisposed)
            {
                // Might as well clear it fully
                _current = null;
            }
            if (_current == null)
            {
                _current = new WebServiceCache();
            }
            return _current;
        }
    }


    public void ClearCache(short percentage)
    {
        try
        {
            if (percentage == 100)
            {
                this.Dispose();
                return;
            }
            var oldest = _current.Min(c => c.Value.LastAccessed);
            var newest = _current.Max(c => c.Value.LastAccessed);
            var difference = (newest - oldest).TotalSeconds;
            var deleteBefore = oldest.AddSeconds((difference / 100) * percentage);
            // LINQ doesn't seem to work very well on concurrent dictionaries
            //var toDelete = _current.Where(c => DateTime.Compare(c.Value.LastAccessed,deleteBefore) < 0);
            var keys = _current.Keys.ToArray();
            foreach (var key in keys)
            {
                if (DateTime.Compare(_current[key].LastAccessed, deleteBefore) < 0)
                {
                    WebServiceCacheObject tmp;
                    _current.TryRemove(key, out tmp);
                    tmp = null;
                }
            }
            keys = null;
        }
        catch
        {
            // If we throw an exception here then we are probably really low on memory
            _current = null;
            GC.Collect();
        }
    }

    public bool IsDisposed { get; set; }
    public void Dispose()
    {
        this.Clear();
        HttpContext.Current.Cache.Remove("CacheTest");
        this.IsDisposed = true;
    }
}
谢谢


Joe

您可以从应用程序中的任何位置访问ASP.NET缓存作为静态属性:

HttpRuntime.Cache
您不需要在请求的上下文中执行此操作(即不需要
HttpContext.Current


因此,您应该使用它,而不是滚动您自己的缓存解决方案。

为什么要这样做?只需使用ASP.NET缓存,不要尝试使用自己的缓存。顺便说一句,您可以将ASP.NET缓存引用为
HttpRuntime.Cache
-您不需要
HttpContext
来使用它。无论我处于页面请求生命周期的哪个阶段,HttpRuntime.Cache是否始终可用?或者如果我从另一个线程或其他什么东西访问它?如果是的话,那太好了,我就用它来代替。如果内存不足,缓存会删除对象并让它们自己处理。如果存在内存压力,垃圾收集器将自行收集对象。修复内存泄漏,而不是试图猜测系统,例如,将过期时间设置为分钟而不是一年,或者指定滑动过期时间分钟,以确保系统中只保留有用的对象cache@Panagiotis:该对象意味着永远不存在,herce the AddYear()。我这样做不是因为我有内存泄漏-我这样做是因为我想缓存很多很多数据,可能比内存中容纳的数据更多。所以你想在内存中缓存比内存中容纳的数据更多的数据?我相信你误解了缓存的作用。也许您应该寻找像memcached或AppFabric缓存这样的解决方案,而不是ASP.NET缓存
HttpRuntime.Cache