#c# #asp.net #.net #caching #garbage-collection
#c# #asp.net #.net #кэширование #сбор мусора
Вопрос:
Мне нужно синхронизировать критический раздел, но только если код работает с теми же данными (определяется идентификаторами объектов). Вот почему я реализовал контейнер объектов блокировки, который динамически создает объекты блокировки на основе идентификатора строки. Объекты блокировки хранятся в словаре и используются повторно, если кто-то запрашивает объект с тем же ключом.
Проблема в том, что миллионы комбинаций ключа блокировки и объектов блокировки в настоящее время остаются в словаре и потребляют память навсегда.
Как создать такой словарь, чтобы он удалял ненужные объекты блокировки и, таким образом, освобождал память?
Мои идеи:
- Храните объекты блокировки как слабые ссылки и просматривайте словарь один раз и удаляйте ключи, где значение!IsAlive
- Храните объекты блокировки как слабые ссылки, но на этот раз реализуйте финализатор в классе LockObject и удалите ключ из словаря при его срабатывании
Есть ли у меня другие варианты?
Комментарии:
1. Небольшое объяснение вашей реальной проблемы, которую вы хотите решить, было бы неплохо.
2. Критический раздел, о котором я говорю, вычисляет, выполняет ли пользователь определенное условие или нет. Условие задается администратором веб-сайта (может быть очень сложным). Оценка состояния может запускаться различными событиями и должна быть синхронизирована, но только для отдельной комбинации идентификаторов пользователя и ConditionID. Помогло ли это?
3. Я
System.Runtime.Caching.MemoryCache
много использовал в подобных случаях4. Ну, насколько я знаю, MemoryCache может освободить элемент, даже если есть ссылка на него где-то еще. Это дисквалифицирует его, потому что я не хочу, чтобы объект освобождался, когда какой-то поток использует его для блокировки. Или я что-то пропустил?
Ответ №1:
Я знаю, что вопрос очень старый, но на случай, если кто-то наткнется на это и столкнется с той же проблемой, взгляните на AsyncKeyedLock, который решает проблему. Вы можете использовать:
using (await _locker.LockAsync(myObject.Id))
{
...
}