Я хотел бы получить совет относительно того, где я могу улучшить или изменить дизайн текущего кода.Словарь кэшированных данных с помощью ReaderWriterLockSlim C#
Существует класс Manager, который настроен и имеет метод вычисления, который вызывается различными потоками. Каждый поток имеет один ресурс, который ему нужно вычислить. Эти ресурсы могут принадлежать различным компаниям. Для каждой компании мы хотим кэшировать некоторые данные, но мы можем получать данные компании только через ресурс, когда вызывается метод Calculate.
Итак, моя идея в настоящее время состоит в том, чтобы иметь словарь в классе Manager с ключом компанииResourceTag в качестве ключа. Когда вызывается Calculate, определяется companyResourceTag и вызывается метод CheckCachedData.
private void CheckCachedData(int companyResourceTag)
{
_ReaderWriterLock.EnterUpgradeableReadLock();
try
{
if (!_CompanyCachedData.ContainsKey(companyResourceTag))
{
Elements elements = ElementService.GetAllElements();
DataElements dataElements = ElementService.GetAllDataElements();
CalendarGroupings calendarGroupings = CalendarService.GetAllCalendarGroupings();
CachedDataContainer cachedItem = new CachedDataContainer(elements, dataElements, calendarGroupings);
_ReaderWriterLock.EnterWriteLock();
try
{
_CompanyCachedData.Add(companyResourceTag, cachedItem);
}
finally
{
_ReaderWriterLock.ExitWriteLock();
}
}
}
finally
{
_ReaderWriterLock.ExitUpgradeableReadLock();
}
}
Если не был предыдущий ресурс от этой компании, то данные этой компании должны быть выбраны с помощью Услуг. Базовые таблицы не часто меняются, и мы можем предположить, что таблицы будут оставаться неизменными за время выполнения вычислений для всех ресурсов. Однако получение этих данных очень трудоемко. Отсюда необходимость кэширования.
Может быть сказано 100 различных компаний и 30000+ ресурсов, которые должны быть рассчитаны. Есть несколько других мест (на ресурс), где этот кэшировать данные считываются из, например:
_ReaderWriterLock.EnterReadLock();
try
{
_CompanyCachedData.TryGetValue(companyResourceTag, out cachedDataContainer);
}
finally
{
_ReaderWriterLock.ExitReadLock();
}
//Do something with cachedDataContainer
Я не пытался сделать код более элегантным из-за комментарий Eric Lathrop здесь: Possible problem
я не использовал ConcurrentDictionary, из-за вопроса, упомянутого здесь: Possible problem with ConcurrentDictionary
Я не уверен, будет ли нормальные замки лучше, чем ReaderWriterLockSlim, но мне нравится идея, что может быть более чем один читатель в и я могу обновить блокировку. В настоящее время я также больше обеспокоен правильностью, чем скоростью.
Правильно ли я использовал RWLS? Согласны ли вы с моим текущим использованием UpgradeableReadLock? Согласны ли вы с моим выбором не использовать ConcurrentDictionary?
«Если бы я хотел улучшить скорость» - то есть, что? При отсутствии четко выраженной наблюдаемой проблемы с производительностью наряду с четко сформулированной целью работы этот вопрос слишком широк. Какие у вас есть доказательства того, что код, который у вас есть сейчас, еще не очень быстрый? Учитывая, что у вас всегда есть вероятность, что вам придется получать данные по сети, и что эта задержка приемлема, трудно поверить, что даже один простой замок вызовет любую реальную проблему. Если RWLS работает, какой конкретный вопрос вы имеете здесь? –
@Peter Duniho: Я отредактировал оригинальный пост, чтобы быть более конкретным. – Igavshne