Должен ли я заблокировать словарь, если я только читаю из него? - PullRequest
3 голосов
/ 01 марта 2020

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

        public void SetModuleLogLevel(string module, LogLevel logLevel)
        {
            if (module == "Other" || !this._moduleToLogLevel.ContainsKey(module)) 
                return;

            lock (this._lock)
            {
                this._moduleToLogLevel[module] = logLevel;
            }
        }

У меня есть еще одна функция, которая возвращает значение из этого словаря. Например,

        private bool IsUrgentToLog(string module, LogLevel logLevel)
        {
            if (!this._moduleToLogLevel.ContainsKey(module)) return false;

            lock (this._lock)
            {
                if (this._moduleToLogLevel[module] < logLevel) return true;
            }

            return false;
        }

Учитывая, что я читаю только из этого словаря в этой функции, нужна ли ему блокировка?

1 Ответ

5 голосов
/ 01 марта 2020

Dictionary<TKey, TValue> не дает никаких гарантий в отношении того, что какой-либо поток изменяет его, т. Е. Вы можете иметь «любое количество читателей» или «не более одного писателя и ноль читателей». Итак: если он может быть видоизмененным: да, вам нужно lock для чтения, чтобы защитить других читателей.

Возможно, вам будет проще использовать ConcurrentDictionary<TKey, TValue> ( любое количество читателей и / или писателей), или если вы не против потерять дженерики: Hashtable (не более одного писателя одновременно с любым количеством читателей, т. е. вам нужно только синхронизировать запись ).

...