Какая коллекция .NET 4.0 System.Collections.Concurrent добавлена ​​в функциональность для .NET 3.0 SynchronizedCollection?

.NET 4.0 представила System.Collections.Concurrent пространство имен:

" System.Collections.Concurrent пространство имен предоставляет несколько потокобезопасные классы коллекций, которые следует использовать вместо соответствующие типы в System.Collections и System.Collections.Generic пространства имен, когда несколько потоков получают доступ к коллекции одновременно "

SynchronizedCollection<T> класс (доступный с .NET 3.0):

"Предоставляет потокобезопасную коллекцию, содержащую объекты типа заданные общим параметром как элементы"

... находится в пространстве имен System.Collections.Generic.

Итак, почему класс SynchronizedCollection<T> является потокобезопасным, но не параллельным?

Что конкретно делает SynchronizedCollection<T> generic class отличным и несовместимым с коллекциями из System.Collections.Concurrent?

Update: Позвольте мне перефразировать вопрос: Что является общим знаменателем и отличает новую функцию во всех общих коллекциях, которые принадлежат пространству имен System.Collections.Concurrent, которое отсутствует (и невозможно в то время как используя SynchronizedCollection<T> общий класс?

Я изменил заголовок на "Что .NET 4.0 System.Collections.Concurrent коллекция добавлена ​​в функциональность для .NET 3.0 SynchronizedCollection?". Но в основном мне интересно узнать, что это делает невозможным на основе .NET 3.0

Update2: Относительно примечания:

"Этот вопрос может уже иметь ответ здесь:

В чем разница между SynchronizedCollection и другие параллельные коллекции?"

Ответ запутан в контексте моего вопроса - это новые функции, эволюционные (с использованием возможностей pre -.NET 4.0) или революционные (недоступные в pre -.NET 4.0)?

Ответ 1

Основное внимание в .NET 4.0 было concurrency. Microsoft представила System.Threading.Tasks пространство имен в .NET 4.0, поэтому было также целесообразно добавить пространство имен System.Collections.Concurrent. Как уже упоминалось, в других местах коллекции в System.Collections.Concurrent очень эффективны, поскольку они реализованы без блокировки. Это непростая задача, и я думаю, именно поэтому Microsoft считает, что она принадлежит к новой крупной версии .NET, а не к обновлению .NET 3.x. AFAIK запрет на поведение, среди прочего, реализован с использованием общей версии Interlocked.CompareExchange, которая также является новой для .NET 4.0.

Если вас интересует, как реализовать классы System.Collections.Concurrent, я рекомендую прочитать книгу Джо Даффи "Параллельное программирование в Windows" , который он написал до выпуска .NET 4.0. В книге показано, как реализованы некоторые из параллельных коллекций.

Ответ 2

Предыдущие классы коллекции, не содержащие потоков, имеют довольно серьезный недостаток, они не могут быть итерированы поточно-безопасным способом. Итерации в целом очень сложно сделать потокобезопасными, нет чистого способа сделать код, который использует итератор, который знает элементы, которые добавляются или удаляются из коллекции, в то время как код выполняет итерацию коллекции. Единственный по-настоящему безопасный способ - заблокировать доступ к коллекции во время итерации. Это очень нежелательно, такой замок обычно удерживается очень долго. Следующим лучшим способом является создание копии коллекции, копия, которая не будет изменена, поэтому ее можно всегда безопасно повторять. Никто не удовлетворяет требованиям хранения O (n) этого решения.

Метод Synchronized() в классах коллекции .NET 1.0 был особенно затруднительным. Microsoft не скрывала, что итерация не является потокобезопасной. Они даже добавили код для обнаружения неудачи, он генерирует исключение, когда поток изменяет коллекцию. Это исключение, однако, не встречается достаточно часто и сбиты с толку. NET-программисты, которые не смогли прочитать предупреждающий ярлык и просто выровнены, предполагают, что, безусловно, потокобезопасная коллекция безопасна независимо от того, что вы делаете. Ну, это не так, и вызов коллекции "поточно-безопасный", когда самая основная операция в коллекции не является потокобезопасной, это, конечно, проблема. То, что Microsoft подразумевало, было "это поточно-безопасное, потому что использование потоков не повредит сбор". То, что прочитали программисты, было "это поточно-безопасное". Microsoft не повторила ту же ошибку в классах коллективной генерации .NET 2.0.

Это было рассмотрено в .NET 4, итерация новых коллекций не вызовет исключения. В противном случае они ничего не сделают, чтобы предотвратить неправильный код вашего кода, поскольку он считывает устаревшие данные. Это неразрешимая проблема, которую вы должны решить самостоятельно.

Ответ 3

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

что это такое, что делало невозможным делать на основе .NET 3.0

Моя догадка ничего сделала невозможным. Я подозреваю, что если вы получите декомпиляцию новых классов в .NET 4.0 и (при необходимости, с синтаксическими изменениями) создайте такие классы самостоятельно против .NET 3.5, они будут работать отлично.

Это то же самое, что, например, Enumerable.Zip можно выполнить вручную в .NET 3.5, если .NET 4.0 недоступен, В самом деле, я помню, где-то видел реализацию LINQ-подобных библиотек для .NET 2.0 (без языковых функций С#, конечно!).

В целом с .NET, если библиотеки не зависят от новых функций CLR, ничего не мешает перепрограммировать библиотеку по сравнению с более ранней версией. Одним из примечательных примеров является дженеричность: до .NET 2.0 не было никакой возможности получить поддержку набора типов типов без ручного управления каждым другим классом, возможно, используя такие инструменты, как CodeSmith.

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