Метод AddOrUpdate в ConcurrentDictionary всегда блокирует (не пропускает, если значения равны) - PullRequest
0 голосов
/ 03 октября 2019

Я прочитал код метода AddOrUpdate в Ссылочный источник и увидел, что, если oldValue и newValue равны, метод все равно выполнит обновление. Это правда? Я правильно понял? Из-за этого метод всегда блокирует.

update: Когда я увидел код метода AddOrUpdate, я подумал: «Почему нам нужно использовать TryUpdate с блокировкой, если oldValue равно newValue? Мы можем проверить уравнениеи вернуть, если значения равны "Из-за этого я задал этот вопрос.

Я понял, почему этот метод всегда обновляет или добавляет, не проверяя равно oldValue и newValue. TValue - это объект, и мы не можем сравнить его без перезаписи метода equals.

Из-за этого, если вы хотите добавить AddOrUpdate без блокировки вашего ConcurrentDictionary, когда oldValue и newValue равны, вам нужно создать метод с вашими классами. Я не знаю, как вы можете сделать это с помощью универсального.

Ответы [ 3 ]

0 голосов
/ 03 октября 2019

Я думаю, что это возможно сделать? Для сравнения сначала используйте IEqualityComparer<TValue>.

public TValue AddOrUpdate<TArg>(TKey key, Func<TKey, TArg, TValue> addValueFactory, Func<TKey, TValue, TArg, TValue> updateValueFactory, TArg factoryArgument)
{
      // key exists, try to update
      if (TryGetValue(key, out oldValue))
      {

           TValue newValue = updateValueFactory(key, oldValue, factoryArgument);
           IEqualityComparer<TValue> valueComparer = EqualityComparer<TValue>.Default;
           if (valueComparer.Equals(oldValue, newValue))
           { return newValue; }
        }
        //...
    }
0 голосов
/ 03 октября 2019

Вы должны использовать ContainsKey перед обновлением.

ContainsKey звонки TryGetValue, которые на линии 509 читаются:

 // We can get away w/out a lock here. 

:)

0 голосов
/ 03 октября 2019

Я понял, почему этот метод всегда обновляет или добавляет, не проверяя равно oldValue и newValue. TValue - это объект, и мы не можем сравнить его без перезаписи метода equals.

Из-за этого, если вы хотите добавить AddOrUpdate без блокировки вашего ConcurrentDictionary, когда oldValue и newValue равны, вам нужно создать метод с вашими классами. Я не знаю, как вы можете сделать это с помощью универсального.

...