У меня есть проект в Asp.Net Core. Этот проект имеет ICacheService, как показано ниже:
public interface ICacheService
{
T Get<T>(string key);
T Get<T>(string key, Func<T> getdata);
Task<T> Get<T>(string key, Func<Task<T>> getdata);
void AddOrUpdate(string key, object value);
}
Реализация просто основана на ConcurrentDictionary<string, object>
, поэтому ее не так сложно, просто сохраняя и извлекая данные из этого словаря. В одной из моих служб у меня есть метод, как показано ниже:
public async Task<List<LanguageInfoModel>> GetLanguagesAsync(string frontendId, string languageId, string accessId)
{
async Task<List<LanguageInfoModel>> GetLanguageInfoModel()
{
var data = await _commonServiceProxy.GetLanguages(frontendId, languageId, accessId);
return data;
}
_scheduler.ScheduleAsync($"{CacheKeys.Jobs.LanguagesJob}_{frontendId}_{languageId}_{accessId}", async () =>
{
_cacheService.AddOrUpdate($"{CacheKeys.Languages}_{frontendId}_{languageId}_{accessId}", await GetLanguageInfoModel());
return JobStatus.Success;
}, TimeSpan.FromMinutes(5.0));
return await _cacheService.Get($"{CacheKeys.Languages}_{frontendId}_{languageId}_{accessId}", async () => await GetLanguageInfoModel());
}
Проблема в том, что у меня есть три параметра в этом методе, которые я использую в качестве ключа кеша. Это прекрасно работает, но проблема в том, что комбинация из трех параметров достаточно высока, поэтому будет так много дублирования объектов в кеше. Я думал создать кеш без дублирования, как показано ниже:
Чтобы иметь кеш со списком в качестве ключа, где я могу хранить более одного ключа для одного объекта. Поэтому, когда я получаю новые элементы, я проверю каждый из них, если он находится в кеше, если он находится в кеше, я добавлю только ключ в список ключей, иначе вставьте новый элемент в кеш. Проблема здесь в том, что тестирование, если объект находится в кеше, является большой проблемой. Я думаю, что он будет потреблять много ресурсов и потребует некоторую сериализацию в конкретную форму, чтобы сделать возможным сравнение, которое снова приведет к сравнению, потребляющему много ресурсов. Кэш может выглядеть примерно так: CustomDictionary<List<string>, object>
Кто-нибудь знает хороший подход к решению этой проблемы, чтобы не дублировать объекты в кеше?
ИЗМЕНИТЬ 1:
Моя основная проблема заключается в том, когда я извлекаю List<MyModel>
из своих List<MyModel>
потому что у них может быть 80% объектов с теми же данными, что резко увеличит размер в памяти. Но это было бы актуально и для простых случаев. Допустим, у меня есть что-то вроде этого:
MyClass o1 = new MyObject();
_cache.Set("key1", o1);
_cashe.Set("key2", o1);
В этом случае, когда я пытаюсь дважды добавить один и тот же объект, я бы не хотел его дублировать, но чтобы key2
каким-то образом указывал на тот же объект, что и key1
. Если это будет достигнуто, это будет проблемой для их недействительности, но я ожидаю иметь что-то вроде этого:
_cache.Invalidate("key2");
Это проверит, есть ли другой ключ, указывающий на тот же объект. Если это так, он удалит только ключ, иначе уничтожит сам объект.