Как это сделать? Я поддерживаю ConcurrentDictionary ключей и каждые 30 минут перебираю ключи для добавления в БД, но боюсь условий гонки (приложение имеет несколько экземпляров, каждый из которых имеет несколько ядер). Вот примерный упрощенный код:
Код: Выделить всё
public class MyMessageConsumer : BaseMessageConsumer
{
private readonly MemoryCache _memoryCache; // key -> [values]
private ConcurrentDictionary _memoryCacheKeys;
private DateTime _lastUpdate;
// not expanding here on the constructors etc that set _lastUpdate etc.
internal async Task UpdateAsync(string cacheKey, string value)
{
await UpdateMemoryCache(cacheKey, keyword);
if (DateTime.Now > _lastUpdate.AddMinutes(30))
{
_lastUpdate = DateTime.Now;
foreach (var (cacheKey, _) in _memoryCacheKeys)
{
if (_memoryCache.TryGetValue(cacheKey, out HashSet values))
{
WriteToSomeDB()
_memoryCache.Remove(RemoveKey(cacheKey));
}
}
}
return MessageConsumeResult.Completed();
}
private async Task UpdateMemoryCache(string cacheKey, string value)
{
if (_memoryCache.TryGetValue(cacheKey, out HashSet previousValues))
{
if (!previousValues.Contains(value))
{
previousValues.Add(value);
_memoryCache.Set(AddKey(cacheKey), previousValues, TimeSpan.FromHours(48));
}
}
else
{
_memoryCache.Set(AddKey(cacheKey), new HashSet { value }, TimeSpan.FromHours(48));
}
}
private string AddKey(string key)
{
_memoryCacheKeys.TryAdd(key, true);
return key;
}
private string RemoveKey(string key)
{
_memoryCacheKeys.TryRemove(key, out _);
return key;
}
}
Большое спасибо за ваши идеи и хорошего дня!
Подробнее здесь: https://stackoverflow.com/questions/783 ... conditions
Мобильная версия