Подтвердить что ты не робот

Существует ли эквивалент класса Guava Striped-Class в С#?

Есть некоторые случаи, когда мне очень нравится использовать класс Guava Striped.

Есть ли эквивалент в С#?

4b9b3361

Ответ 1

Не похоже, что существует прямой эквивалент, но есть некоторые блокирующие потоковые варианты коллекции (я не уверен, чего вы пытаетесь достичь, поэтому я не могу сказать, будут ли они работать ваш сценарий). Посмотрите System.Collections.Concurrent Namespace.

В частности, ConcurrentBag, ConcurrentQueue, ConcurrentStack и ConcurrentDictionary имеют разные стратегии блокировки/блокировки потоков. Некоторые из них объясняются в этом сообщении в блоге.

Возможно, вы сможете получить то, что хотите, через класс Partitioner, хотя я не уверен в реализации.

@Behrooz неверно заявляет, что для всех типов фреймов .net используется только один замок для всего списка. Взгляните на источник для ConcurrentDictionary. Строка 71 предполагает, что этот класс реализован с использованием нескольких блокировок.

Если вы действительно этого захотите, вы можете написать свою собственную версию. Источник для Guava Striped: https://github.com/google/guava/blob/master/guava/src/com/google/common/util/concurrent/Striped.java

Ответ 2

Я думаю, что лучше всего вы можете реализовать свою собственную, потому что все типы инфраструктуры dotnet предлагают только один lock для всего списка.
Для этого вы можете использовать функцию GetHashCode(), модуль (%) с количеством полос, которые вы хотите. и использовать его как индекс для Tuple<TLock, List<T>>[], где TLock может быть любой блокировкой, определенной в пространстве имен System.Threading, а T - типом, который вы хотите сохранить/получить. С этим вы можете решить, как вы хотите, чтобы ваши полосы были сохранены. Существуют такие варианты, как HashSet (неэффективны в вашем случае, поскольку вы уже используете некоторые из битов для вычисления индекса полосы), SortedSet, List, Array.

Кстати, спасибо за вопрос, Он поможет мне решить проблему, с которой я столкнулся.

Ответ 3

Вы пробовали Tamarind из NuGet?
Это порт С# библиотеки Google Guava

Ответ 4

Я думаю, что ConcurrentDictionary может архивировать аналогичный результат.

Основываясь на их документации:

Все эти операции являются атомарными и являются потокобезопасными применительно ко всем другим операциям в классе ConcurrentDictionary. Единственными исключениями являются методы, которые принимают делегат, то есть AddOrUpdate и GetOrAdd. Для модификаций и операций записи в словарь ConcurrentDictionary использует мелкозернистую блокировку для обеспечения безопасности потоков. (Операции чтения в словаре выполняются без блокировки). Однако делегаты для этих методов вызывают внешние блокировки, чтобы избежать проблем, которые могут возникнуть при выполнении неизвестного кода под блокировкой. Поэтому код, выполняемый этими делегатами, не зависит от атомарности операции.

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