Контекст
Я пытаюсь реализовать веб-службу API REST, которая "оборачивает" существующую программу на Си.
Проблема / цель
Учитывая, что программа на C имеет медленное время инициализации и высокое использование ОЗУ, когда я говорю ей открыть определенную папку (предположим, это не может быть улучшено), я имею в виду кэширование дескриптора / объекта C, поэтому следующийКогда запрос GET попадает в ту же папку, я могу использовать существующий дескриптор.
То, что я пробовал
Сначала объявляем статическое сопоставление словаря из пути к папке для обработки:
static ConcurrentDictionary<string, IHandle> handles = new ConcurrentDictionary<string, IHandle>();
В моей функции GET:
IHandle theHandle = handles.GetOrAdd(dir.Name, x => {
return new Handle(x); //this is the slow and memory-intensive function
});
Таким образом, всякий раз, когда определенная папка была получена ранее, она уже будет иметь готовый для использования дескриптор.
Почему это нехорошо
Так что теперь я рискую исчерпать память, если слишком много папок кэшируется одновременно.Как я могу добавить GC-подобный фоновый процесс к TryRemove()
и вызвать IHandle.Dispose()
на старых дескрипторах, возможно, в политике наименьшего недавно использовавшегося или наименьшего часто используемого?В идеале он должен запускаться только при низком доступном объеме физической памяти.
Я попытался добавить следующий оператор в функцию GET, но он выглядит слишком хакерским и очень ограниченным по функциям.Этот способ работает нормально, только если я всегда хочу, чтобы срок действия маркеров истек через 10 секунд, и он не перезапускает таймер, если последующий запрос поступает в течение 10 секунд.
HostingEnvironment.QueueBackgroundWorkItem(ct =>
{
System.Threading.Thread.Sleep(10000);
if (handles.TryRemove(dir.Name, out var handle2))
handle2.Dispose();
});
Чем этот вопрос не является
Я не думаю, что кэширование выходных данных является решением здесь.После того, как я верну результат этого запроса GET (это просто метаданные содержимого папки), может быть другой запрос GET для получения более подробных данных, который требует вызова методов Handle
.
Iнадеюсь, мой вопрос достаточно ясен!