0

私は今、この問題を何ヶ月も抱えています。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. ロックを解除し、スレッドが 1 つだけ使用されていることを確認します。
  2. cacheItems ではなく、unsortedItems コレクションに 1 つのロックを配置します。
  3. たとえば、最初に (string)x と (string)y を比較してから、適切な順序でロックするなど、何らかの方法でアイテムをロックする順序を見つけます。
  4. 他の: ...

あなたは何を好むか?

4

1 に答える 1

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;
  }
于 2012-07-03T20:08:53.580 に答える