Каков наилучший способ добавления / удаления определенного элемента из списка <T>в многопоточном сценарии - PullRequest
6 голосов
/ 09 ноября 2011

У меня сейчас есть сценарий, который должен добавлять и удалять элементы в многопоточном состоянии

Я делаю

lock(list)
{
    if(!list.Contains(item))
    {
        list.Add(Item);
    }
}

и

lock(list)
{
    if(list.Contains(item))
    {
        list.Remove(Item);
    }
}

НоУ меня сейчас очень большая проблема с состоянием гонки.Время блокировки увеличивается и увеличивается.

Я хотел бы использовать ConcurrentBag, но у него нет метода Contains, поэтому я не могу удалить конкретный элемент, который хочу удалить.

IСейчас я использую ConcurrentDicionary в качестве временного решения.но это определенно не правильный способ сделать это.

Итак, мой вопрос, как я могу решить эту проблему?Есть ли какая-нибудь свободная реализация для подобных вещей?Потому что ни одна из коллекций под параллельным пространством имен не подходит для этой проблемы.

Ответы [ 2 ]

5 голосов
/ 09 ноября 2011

Требуется одновременная версия HashSet<T>. ConcurrentBag<T> не предназначен для этого, он предназначен для поддержки эффективных сценариев производитель-потребитель. В Framework нет такой коллекции.

Итак, вы можете использовать ConcurrentDictionary<Item, Item>, как вы сказали. Но я согласен с вами, что это не идеальное решение.

Или вы можете заменить код блокировки, который использует List<T>, на код, который использует HashSet<T>. Операции типа Contains() и Remove() могут быть очень медленными в больших списках. Но они должны быть быстрыми в хэш-наборах, которые должны значительно улучшить вашу производительность, если ваша коллекция достаточно велика.

Также возможно, что есть какая-то сторонняя библиотека, которая содержит что-то вроде ConcurrentHashSet<T>, но я не знаю ни о чем.

0 голосов
/ 09 ноября 2011

Просто создайте бессмысленный объект для управления блокировкой:

object listLock = new object();

lock(listLock)
{
    if(!list.Contains(item))
    {
        list.Add(Item);
    }
}

Я считаю, что обычно это стандартный способ блокировки из-за описанной выше проблемы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...