Потокобезопасные коллекции в .NET - PullRequest
65 голосов
/ 05 июня 2010

Что является стандартом в настоящее время, когда требуется потокобезопасная коллекция (например, Set). Синхронизирую ли я его сам или существует коллекция потоков, по своей сути безопасная?

Ответы [ 4 ]

98 голосов
/ 05 июня 2010

.NET 4.0 Framework представляет несколько потоковобезопасных коллекций в пространстве имен System.Collections.Concurrent :

ConcurrentBag
Представляет потокобезопасную неупорядоченную коллекцию объектов.

ConcurrentDictionary
Представляет потокобезопасную коллекцию пар ключ-значение, к которым могут одновременно обращаться несколько потоков.

ConcurrentQueue
Представляет потокобезопасную коллекцию «первым пришел - первым вышел» (FIFO).

ConcurrentStack
Представляет коллекцию LIFO, ориентированную на многопотоковое исполнение.


Другие коллекции в .NET Framework по умолчанию не поддерживают потокобезопасность и должны быть заблокированы для каждой операции:

lock (mySet)
{
    mySet.Add("Hello World");
}
18 голосов
/ 05 июня 2010

До .net 4.0 большинство коллекций в .Net не являются поточно-ориентированными. Вам придется самостоятельно поработать с синхронизацией: http://msdn.microsoft.com/en-us/library/573ths2x.aspx

Цитата из статьи:

Коллекции классов могут быть сделаны потоком безопасно использовать любой из следующих методы:

Создайте потокобезопасную оболочку, используя Синхронизированный метод и доступ к Коллекция исключительно через это обертка.

Если у класса нет Синхронизированный метод, производный от Класс и реализовать синхронизированный метод с использованием свойства SyncRoot.

Используйте механизм блокировки, такой как оператор блокировки в C # (SyncLock в Visual Basic), на SyncRoot свойство при доступе к коллекция.

Синхронизировать корневое свойство
Заявление о блокировке

Object thisLock = new Object();
......
lock (thisLock)
{
    // Critical code section
}

В .net 4.0 введено System.Collections.Concurrent пространство имен

Коллекция блокировок
Параллельная сумка
Одновременная очередь
Словарь одновременно
Ordable Partitioner
Разметка
Partitioner T

4 голосов
/ 05 июня 2010

.NET 4 предоставляет набор потоковобезопасных коллекций в System.Collections.Concurrent

1 голос
/ 12 июня 2015

В дополнение к очень полезным классам в System.Collections.Concurrent, одна стандартная методика в сценариях «в основном читают редко меняются» (или, если есть, однако, частые, но не одновременные записи), которая также применима к .Netс именем Копирование при записи .

Имеет несколько свойств, которые желательны в высококонкурентных программах:

  • collectionСами экземпляры объектов являются неизменяемыми (т. е. потокобезопасными, их можно безопасно перечислить без блокировки).
  • Модификация может занимать столько времени, сколько необходимо, производительность и параллелизм чтения не затрагиваются
  • реализован в общем случае , чтобы превратить любую структуру данных, которая не является поточно-ориентированной, в структуру, которая является

Ограничение: при одновременных записях модификации, возможно, придется повторить, поэтому чем большеодновременные записи получают, тем менее эффективными они становятся.(Это оптимистичный параллелизм в работе)

Редактировать Комментарий Скотта Чемберлена напомнил мне, что есть еще одно ограничение: если ваши структуры данных огромны, и изменения происходят часто, копия-все-при-записи может быть непомерно как с точки зрения потребления памяти, так и с точки зрения затрат на копирование ЦП.

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