我有这个问题好几个月了。我从 entlib 4.1 升级到 5。我的应用程序正在缓存越来越多的项目。有时(有时一天三次)CPU 以 100% 的使用率挂起,但应用程序保持响应。发生这种情况时,我使用 dotTrace 获取快照,并且似乎大部分时间都花在PriorityDateComparer.Compare
. 此比较器仅由 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:如果我的第一个问题的答案是否定的,那么我们如何解决这个问题?我看到了一些可能性:
- 移除锁定并确保只使用一个线程。
- 将一把锁放在 unsortedItems 集合上而不是 cacheItems 上。
- 以某种方式找出锁定项目的顺序,例如首先比较 (string)x 和 (string)y,然后以正确的顺序锁定它们。
- 其他: ...
你喜欢哪个?