У меня есть несколько потоков, запрашивающих данные, которые нужно загружать по сети. Чтобы иметь меньше сетевого трафика и более быстрые ответы, я хотел бы кэшировать данные, которые часто запрашиваются. Я также хочу ограничить размер данных кэша.Как реализовать кеширование с ограничением размера данных?
Мой класс выглядит примерно так:
public class DataProvider
{
private ConcurrentDictionary<string, byte[]> dataCache;
private int dataCacheSize;
private int maxDataCacheSize;
private object dataCacheSizeLockObj = new object();
public DataProvider(int maxCacheSize)
{
maxDataCacheSize = maxCacheSize;
dataCache = new ConcurrentDictionary<string,byte[]>();
}
public byte[] GetData(string key)
{
byte[] retVal;
if (dataCache.ContainsKey(key))
{
retVal = dataCache[key];
}
else
{
retVal = ... // get data from somewhere else
if (dataCacheSize + retVal.Length <= maxDataCacheSize)
{
lock (dataCacheSizeLockObj)
{
dataCacheSize += retVal.Length;
}
dataCache[key] = retVal;
}
}
return retVal;
}
}
Моей проблема: как я могу убедиться, что dataCacheSize
всегда имеют правильное значение? Если два потока одновременно запросят одни и те же нераскрытые данные, они оба будут записывать свои данные в кэш, что не представляет проблемы, поскольку данные одинаковы, а второй поток просто перезаписывает кэшированные данные теми же данными. Но откуда я могу узнать, если он был перезаписан или нет, чтобы не считать его размер дважды?
Это может также случиться, что два потока добавление данных в то же время, в результате чего размера DataCache больше, чем разрешено ...
Есть элегантный способ выполнить эту задачу без добавления сложных механизмов запирающих?
Вместо того, чтобы пытаться кэшировать «рулон», взгляните на System.Runtime.Caching.MemoryCache. https://msdn.microsoft.com/en-us/library/system.runtime.caching.memorycache(v=vs.110).aspx – Kevin
Хорошо, MemoryCache, похоже, выполняет эту работу. Однако я должен проверить параметры управления кешем. Вы хотите ответить на вопрос? Я не могу принять комментарий. – Ben
Добавлено ответ. Спасибо – Kevin