私は今、この問題を何ヶ月も抱えています。entlib 4.1 から 5 にアップグレードしました。私のアプリケーションはますます多くの項目をキャッシュしています。時々 (1 日に 3 回)、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: 2 つのキャッシュ アイテムが常に同じ順序でロックされていると確信できますか? SortedList の実装を調べると、そうではないと思います。
質問 2: 最初の質問に対する答えが「いいえ」の場合、どうすれば解決できますか? いくつかの可能性があります:
- ロックを解除し、スレッドが 1 つだけ使用されていることを確認します。
- cacheItems ではなく、unsortedItems コレクションに 1 つのロックを配置します。
- たとえば、最初に (string)x と (string)y を比較してから、適切な順序でロックするなど、何らかの方法でアイテムをロックする順序を見つけます。
- 他の: ...
あなたは何を好むか?