Безопасен ли поток FrozenDictionary<TKey,TValue> в .NET 8?

У меня очень простой вопрос:

безопасно ли читать одновременно экземпляр FrozenDictionary<TKey,TValue> из разных потоков?

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

По моему опыту, потокобезопасность всегда явно документируется в документации Microsoft и никогда не рассматривается как «неявная». Например, потокобезопасность ImmutableDictionary<TKey,TValue>явно документирована.

Кто-нибудь имеет представление об этом?

Есть ли причина, по которой вы бы предпочли использовать FrozenDictionary<,> вместо ImmutableDictionary<,>, учитывая, что последний дает вам гарантию, которую вы, похоже, ищете?

Damien_The_Unbeliever 28.08.2024 09:38

Я бы выбрал ImmutableDictionary<TKey,TValue>, мне просто было любопытно.

Enrico Massone 28.08.2024 09:49

Следует отметить одну вещь: FrozenDictionary — это абстрактный класс, а ImmutableDictionary — запечатанный класс, встроенные реализации должны быть потокобезопасными.

shingo 28.08.2024 09:56

«Обеспечивает неизменяемый словарь, доступный только для чтения» — как это может быть небезопасным для потоков? Если он создается один раз, вы не можете иметь устаревшие данные при его использовании. Я что-то упускаю?

Fildor 28.08.2024 10:01

@ Филдор, это именно то, что я понимаю, я просто искал подтверждение из документов.

Enrico Massone 28.08.2024 10:05

Я предполагаю, что это просто недосмотр в документации. Если в контракте есть эти требования, единственной проблемой, которую я мог бы себе представить, была бы изменчивость TValue.... так что, может быть, это одна из тех «в основном» потокобезопасных ситуаций? Однако если ваше TValue также неизменяемо, создать проблему будет довольно сложно.

Fildor 28.08.2024 10:09

Неизменяемость @Fildor и доступность только для чтения — это внешнее поведение коллекции. Это не гарантирует, что внутренние структуры данных коллекции неизменны. Теоретически возможно, что коллекция оптимизирует внутреннее хранилище данных по соображениям производительности каждый раз, когда считывается ключ. Я считаю, что это маловероятно, но без поддержки документации я не уверен на 100%.

Theodor Zoulias 28.08.2024 10:31

@TheodorZoulias Это звучит разумно, да. Это возвращает нас к «в основном поточно-ориентированному, но, возможно, не всегда»… что можно рассматривать как «достаточно поточно-ориентированному для определенных случаев использования»…

Fildor 28.08.2024 10:45

@Fildor «достаточно потокобезопасен для определенных вариантов использования» требует, чтобы варианты использования были конкретными и однозначными. Например, Dictionary<K,V> является потокобезопасным для чтения, когда нет авторов. Я знаю это, потому что так написано в документации. Без поддержки со стороны документации или, по крайней мере, какого-либо косвенного указания на намерение из другого официального источника (например, GitHub), как мы можем сказать, каковы потокобезопасные варианты использования замороженной коллекции?

Theodor Zoulias 28.08.2024 11:00

@TheodorZoulias "как мы можем сказать, какие варианты использования потокобезопасны" - Мы не можем. ИМХО, это действительно упущение со стороны MS.

Fildor 28.08.2024 11:02

@Fildor, если тип / компаратор работает таким образом: это повлияет на любую коллекцию, поэтому: если ImmutableWhatever можно сделать заявление о потокобезопасности: то же самое можно и FrozenWhatever

Marc Gravell 28.08.2024 11:03

@MarcGravell Да, теперь я понимаю. И я полностью согласен с вашими соображениями в вашем ответе.

Fildor 28.08.2024 11:05
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
5
12
61
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

По моему взвешенному мнению, это ошибка документации, и ее следует устранить соответствующим образом; намерение состоит в том, что я на 99,9% уверен, что это действительно неизменяемая сущность, доступная только для чтения, и если мы игнорируем злоупотребление отражением (поскольку все ставки здесь, на любой тип), это потокобезопасно. Конструктор является внутренним, поэтому нам не нужно беспокоиться об экзотических пользовательских реализациях — только о встроенных реализациях (пустых, маленьких, по умолчанию и т. д.), которые все (при беглом просмотре) кажутся реализованными. соответственно (это не окончательный обзор, заметьте).

ИМХО: зарегистрируйте проблему с документацией

Спасибо за ответ. Интересно, что общедоступный API на самом деле предоставляет что-то, что можно использовать для внутренней модификации. Learn.microsoft.com/en-us/dotnet/api/…

Enrico Massone 28.08.2024 11:27

@EnricoMassone Возвращает readonly ref, поэтому вам придется использовать Unsafe, чтобы изменить его. А если вы используете небезопасный код, все ставки всегда отключены.

canton7 28.08.2024 11:28

Вы правы, это ссылка только для чтения, а не простая ссылка. Спасибо, что указали на это.

Enrico Massone 28.08.2024 11:30

Ваше предположение верно: если какой-либо объект доступен только для чтения и/или вы уверены, что он неизменен и не будет изменен, то я не вижу причин беспокоиться о безопасности потоков. Потокобезопасность означает параллельные операции без возникновения состояний гонки или взаимоблокировок. Если ясно, что объект не будет изменен, то не нужно беспокоиться о его потокобезопасном чтении.

https://learn.microsoft.com/en-us/dotnet/api/system.collections.frozen.frozendictionary-2?view=net-8.0

Из данного источника; FrozenDictionary<TKey,TValue> является неизменяемым и оптимизирован для ситуаций, когда словарь создается нечасто, но часто используется во время выполнения. Его создание требует относительно высоких затрат, но обеспечивает превосходную производительность поиска. Таким образом, он идеален для случаев, когда словарь создается один раз, возможно, при запуске приложения, и используется на протяжении всего оставшегося срока службы приложения.

Другие вопросы по теме