Какой элемент возвращает ConcurrentDictionary.ElementAt

В моем коде я получил ConcurrentDictionary, теперь я хочу перебирать каждый элемент в Словаре, но если условие истинно, я хочу удалить элемент из этого Словаря, чтобы не использовать цикл foreach. Также может случиться, что Словарь получит новый элемент в цикле или удалит его из другого потока. После некоторых исследований я использовал ElementAt.

Теперь мой вопрос, будет ли ConcurrentDictionary освободить индексы снова, как это делает List. Так что первый элемент всегда будет иметь индекс 0.

Вот как выглядит мой код, CommandHandler.Timeouter из ConcurrentDictionary:

int current = 0;

while (CommandHandler.Timeouter.Count() > current)
{
    var info = CommandHandler.Timeouter.ElementAt(current);
    var timeoutcooldown = info.Value.LastCommandTime.AddMinutes(1);

    if (timeoutcooldown < DateTime.UtcNow)
       {
           CommandHandler.Timeouter.TryRemove(info.Key, out _);
       }
    else current++;
}

1 ответ

ElementAt просто рассматривает словарь как IEnumerable<KeyValuePair<TKey, TValue>>, Словари не заказаны. Индекс поэтому бессмысленный. Думайте об элементах, возвращающихся в случайном порядке каждый раз. Также, ElementAt не может сделать эту тему безопасной.

Кажется, вы хотите реализовать срок действия кэша. Рассмотрим только использование lock чтобы получить доступ к обычному словарю. Если не так много споров, это будет самое простое и очень быстрое решение.

Альтернативный шаблон кода для этого цикла будет следующим:

var itemsToExpire = myDict.Where(/* compute expiration */).ToList();
foreach (var item in itemsToExpire)
   myDict.Remove(item);

Нет необходимости в каких-либо сложных циклах.

Другие вопросы по тегам