我现在已经有好几个月了。我从entlib 4.1升级到5.我的应用程序正在缓存越来越多的项目。有时(有时一天三次)CPU会以100%的使用率挂起,但应用程序会保持响应。当发生这种情况时,我使用dotTrace来获取快照,并且似乎大部分时间都花费在PriorityDateComparer.Compare
上。此Comparer仅由System.Collections.SortedList的构造函数使用,并包含此正文:
public int Compare(object x, object y)
{
CacheItem leftCacheItem = (CacheItem)unsortedItems[(string)x];
CacheItem rightCacheItem = (CacheItem)unsortedItems[(string)y];
lock (rightCacheItem)
{
lock (leftCacheItem)
{
if (rightCacheItem == null && leftCacheItem == null)
{
return 0;
}
if (leftCacheItem == null)
{
return -1;
}
if (rightCacheItem == null)
{
return 1;
}
return leftCacheItem.ScavengingPriority == rightCacheItem.ScavengingPriority
? leftCacheItem.LastAccessedTime.CompareTo(rightCacheItem.LastAccessedTime)
: leftCacheItem.ScavengingPriority - rightCacheItem.ScavengingPriority;
}
}
}
问题1:我们能确定两个缓存项始终以相同的顺序锁定吗?如果我检查SortedList的实现,我不这么认为。
问题2:如果我的第一个问题的答案是否那么我们如何解决这个问题?我看到了一些可能性:
你更喜欢什么?
答案 0 :(得分:0)
我更改了比较器,因此无需查找缓存项:
int IComparer<CacheItem>.Compare(CacheItem leftCacheItem, CacheItem rightCacheItem)
{
lock (rightCacheItem)
{
lock (leftCacheItem)
{
if (rightCacheItem == null && leftCacheItem == null)
{
return 0;
}
if (leftCacheItem == null)
{
return -1;
}
if (rightCacheItem == null)
{
return 1;
}
return leftCacheItem.ScavengingPriority == rightCacheItem.ScavengingPriority
? leftCacheItem.LastAccessedTime.CompareTo(rightCacheItem.LastAccessedTime)
: leftCacheItem.ScavengingPriority - rightCacheItem.ScavengingPriority;
}
}
}
在Microsoft.Practices.EnterpriseLibrary.Caching.ScavengerTask
中,我相应地改变了调用方法:
private static SortedList SortItemsForScavenging(Hashtable unsortedItemsInCache)
{
return new SortedList(unsortedItemsInCache, new PriorityDateComparer(unsortedItemsInCache));
}
到
private static List<CacheItem> SortItemsForScavenging(Hashtable unsortedItemsInCache)
{
List<CacheItem> cacheValues = new List<CacheItem>(unsortedItemsInCache.Values.Cast<CacheItem>());
cacheValues.Sort(new PriorityDateComparer());
return cacheValues;
}