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