Привет.
Помогите оптимизировать метод.
Использую ConcurrentDictionary<string, string> в многопоточной програмке.
Мне нужно просто периодически (раз в 10 минут) пройтись по коллекции и удалить из нее элементы, которые не проходят по условию (если конкретно - мне просто нужно чистить словарик от устаревших записей, которые никто уже не запросит и они так и будут висеть вечно, если их не удалить).
Проверка условия происходит по value а не key. Если бы проверка происходила по ключу, то проблемы бы конечно не было бы.
Я конечно могу запросить массив values и пройтись по нему, но найдя те, что нужно удалить, я не имею ссылки на ключ.
Таким образом я пришел к такому решению:
var keys = myDict.Keys;
foreach (string key in keys)
{
string str;
if (myDict.TryGetValue(key, out str))
{
if ( условие )
myDict.TryRemove(key, out str /*значение str нам уже не интересно, но прототип функции таков*/);
}
}
Как я написал выше - метод всего лишь служебный, чистящий. Поэтому части данных уже может не быть во время чистки (кто-то их удалил уже), поэтому и используются TryGetValue и TryRemove.
В моем решении я вынужден проходить по всему списку и для каждого ключа постоянно запрашивать его значение. Мне это не нравится, ведь речь все же идет о многопоточном словарике, а значит постоянно будут использоваться блокировки.
Я конечно предполагаю, что это все не займет сильно много времени - но все же, из любви к искусству и перфекционизму хотелось бы найти более эффективное решение.
Помогите решить задачку пожалуйста.
В LINQ дофига полезных методов, для работы с коллекциями, может какой-то может помочь в моей задаче ?
Хотя не уверен, что IEnumerable корректно заточен для работы с многопоточными коллекциями.
Как известно запрещено изменять коллекцию, по которой идет энумератор (т.е. нельзя идти внутри foreach и тут же в цикле удалять элементы из проходимого перечисления) - но т.к. речь идет об ConcurrentDictionary, то удалить элемент может кто-то другой.
Можно ли как-то получить сразу все значения KeyValuePair из словаря, чтобы спокойно их проверить (а не только в цикле foreach)? Это бы полностью решило проблему. Но насколько я знаю эту структуру возвращает лишь метод Enumerator.Current, т.е. придется идти по всему циклу - а как я написал выше, я опасаюсь использовать энумератор в конкурентных структурах.