Какой элемент возвращает ConcurrentDictionary.ElementAt - PullRequest
0 голосов
/ 11 ноября 2018

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

Теперь мой вопрос, будет ли 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 Ответ

0 голосов
/ 11 ноября 2018

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

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

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

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

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

...