Протоколы блокировки словаря .NET / C # - PullRequest
0 голосов
/ 27 сентября 2018

Мне нужно точно понимать проблемы блокировки и параллелизма с коллекцией словаря .NET, а не с ConcurrentDictionary.Предположим, у меня есть словарь, определенный как key = string, value = SomeOtherRandomClass.

  1. Должен ли весь словарь быть заблокирован от записи во время вызова TryGetValue ("abc")?

  2. Если можно гарантировать, что никакие ключи не будут добавлены / удалены во время вызова TryGetValue - нужно ли по-прежнему блокировать запись для всего словаря?

  3. При успешном вызове TryGetValue, должен ли быть заблокирован весь словарь, пока изменяется соответствующее значение (SomeOtherClass)?Или только этот конкретный ключ, чтобы два человека не могли обновить один и тот же (SomeOtherClass) одновременно.

Я считаю, что наиболее логичными являются ответы да, нет, а затем нет и да, чтобы# 3.Но я бы хотел быть абсолютно уверенным.Но я могу представить реализации, где ответом на вопрос № 1 будет «нет».

Ответы [ 2 ]

0 голосов
/ 27 сентября 2018

Должен ли весь словарь быть заблокирован от записи во время вызова TryGetValue ("abc")?

Да, потому что реализация словаря не является поточно-ориентированной.

Если можно гарантировать, что никакие ключи не будут добавлены / удалены во время вызова TryGetValue - нужно ли блокировать запись по-прежнему всему словарю?

Нет, этоне возможно и да, это все еще должно быть заблокировано от записи.Я не знаю, что означает «весь словарь» ... вам нужна эксклюзивная блокировка, которая не позволяет двум потокам выполнять код в одном словаре.Это связано с тем, что реализация словаря не является поточно-ориентированной.

При успешном вызове TryGetValue должен ли быть заблокирован весь словарь, пока изменяется соответствующее значение (SomeOtherClass)?Или только этот конкретный ключ, чтобы два человека не могли обновить один и тот же (SomeOtherClass) одновременно.

Если вы изменяете само значение (например, вызываете dictionary[key] = value), тогда да, это должно бытьзаперта.Если значение является ссылочным типом, и вы не изменяете ссылку, а просто модифицируете объект, на который ссылается, словарь не нужно блокировать, поскольку вы не выполняете какой-либо код словаря, который не является поточно-ориентированным.

0 голосов
/ 27 сентября 2018

Dictionary не предназначен для многопоточности. Каждая операция в экземпляре Dictionary (операции чтения и записи) должна быть заблокирована (в идеале - в свойстве Dictionary SyncRoot), если к ней будут обращаться несколько потоков, или вы рискуетеразвращает Dictionary.Нет возможности заблокировать только один конкретный ключ.

Тем не менее, Dictionary не заботится о внутренностях его значений , так что, как только вы получите значение, выне нужно держать Dictionary заблокированным во время чтения или изменения самого значения - если только несколько потоков не будут обращаться к каждому значению тоже (но тогда вы можете избежать блокировки только этого значения).Все это зависит от требований вашего приложения, но вам необходимо выполнить ту же работу с ConcurrentDictionary.

Также обратите внимание, что ConcurrentDictionary защищает только отдельные операции.Если два потока попытаются получить значение для определенного ключа и изменить значение этого ключа на единицу больше, чем раньше, у вас все равно будет состояние состязания без ручной блокировки операций чтения и записи.

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