используя ConcurrentStack - PullRequest
       2

используя ConcurrentStack

4 голосов
/ 23 октября 2010

Мне нужно использовать структуру данных стека для сохранения строк. Но этот стек будет доступен из нескольких потоков. Поэтому мой вопрос: как мне использовать ConcurrentStack для добавления данных из нескольких потоков?

Ответы [ 5 ]

9 голосов
/ 23 октября 2010

Поздравляем, вы выбрали правильный контейнер для многопоточного использования.Весь класс является поточно-ориентированным и рекомендуется для вашего сценария, поэтому просто используйте Push или PushRange в зависимости от ситуации.

Пример кода диапазонов здесь использует распараллеливание для демонстрациимногопоточная операция.

8 голосов
/ 23 октября 2010

Вы уже получили довольно хорошие ответы. Позвольте мне предоставить некоторую полезную информацию относительно его дизайна, чтобы помочь вам лучше понять, как его можно использовать. Обратите внимание, что нет метода Pop. Это потому, что дизайнеры хотели помешать вам выполнить следующую небезопасную последовательность операций. Это небезопасно, потому что последовательность вызовов свойства Count и гипотетического метода Pop не является атомарной, несмотря на то, что сбор выставляется как поточно-ориентированный.

while (stack.Count > 0)
{
  stack.Pop();
}

Для согласования этого общего случая использования разработчики использовали метод TryPop. Это, по сути, позволяет переписать вышеизложенное, как показано ниже. На этот раз код безопасен.

object item;
while (stack.TryPop(out item))
{
  // Do something with the item here.
}

Следствие моего первого примера также существует с методом Push. Следующий код (который на этот раз допустим) также небезопасен.

if (stack.Count < MAX_ITEMS)
{
  stack.Push(...);
}

Последний пример не так распространен, как предыдущий, и, вероятно, поэтому разработчики не добавили CAS -подобную эквивалентную операцию TryPush. Возможно, в будущем выпуске, который будет нам доступен.

1 голос
/ 23 октября 2010

Использование по одному в потоке:

_stack.Push(obj);

В другом потоке используйте:

MyObj obj;    
if (_stack.TryPop(out obj))
    UseObj(obj);

Я рекомендую прочитать это сообщение в блоге MSDN .

1 голос
/ 23 октября 2010

Добавление значений к ConcurrentStack из нескольких потоков довольно просто. Просто сделайте ссылку на стек доступной и вызовите Push из того потока, который необходим для добавления данных. Никакой специальной блокировки здесь не требуется, поскольку коллекция предназначена для использования таким образом из нескольких потоков.

1 голос
/ 23 октября 2010

Вы создаете ConcurrentStack<string> и убедитесь, что все потоки имеют ссылку на него.

Тогда потоки просто вызовут Push , чтобы добавить строки:

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