У меня эта проблема уже несколько месяцев. Я обновил от entlib 4.1 до 5. Мое приложение кэширует все больше предметов. Время от времени (иногда трижды в день) процессор зависает при 100% использовании, но приложение остается отзывчивым. Я использовал dotTrace для получения моментального снимка, когда это происходит, и кажется, что большую часть времени тратится на PriorityDateComparer.Compare
. Это Comparer используется только конструктору System.Collections.SortedList и содержит это тело:EntLib 5 Кэширование - подозрительный тупик - процессор стоит на 100%
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, а затем заблокируйте их в правильном порядке.
- другие: ...
Что вы предпочитаете?
Хорошо, это не тупик. Заглядывая ближе в след: есть только один поток, вызывающий компаратор. Взглянув в код: перед использованием компаратора в кешмангере помещается блокировка. Я убежден, что этот код не выполняется одновременно. Глядя снова на след: большинство времени в Сравнить занято System.Collections.HashTable.get_Item (o). Таким образом, этот компаратор используется для сортировки HashTable. Совсем не лучшая практика: [можно сортировать хэш-таблицу] (http://stackoverflow.com/questions/675759/is-it-possible-to-sort-a-hashtable). –