ConcurrentDictionary - неработающий словарь или плохой код? - PullRequest
5 голосов
/ 06 января 2012

Хорошо, поэтому я столкнулся со странной маленькой проблемой и, честно говоря, у меня нет идей.Я хотел показать это, чтобы увидеть, что я упустил что-то, что я сделал неправильно, или ConcurrentDictionary работает неправильно.Вот код:

(Cache - это класс, содержащий статические ключи ConcurrentDictionary)

var tmp = Cache.Keys.GetOrAdd(type,
                key =>
                {
                    var keys = context.GetKeys(key);
                    if (keys.Count() == 1)
                    {
                        return new KeyInfo
                            {
                                Name = keys.First().Name,
                                Info = key.GetInfo(keys.First().Name)
                            };
                    }

                    return null;
                });

            if (tmp == null)
                Cache.Keys.TryRemove(type, out tmp);

            return tmp;

Проблема в том, что иногда tmp равен null, в результате чего строка TryRemoveзапустить, но строка return null; выше никогда не попадет.Поскольку return null - единственное, что помещает null в словарь и никогда не запускается, как tmp может быть null?


Включая класс Cache (SetNames не используетсяпо этому коду):

public class Cache
{
    public static ConcurrentDictionary<Type, Info> Keys = new ConcurrentDictionary<Type, Info>();
    public static ConcurrentDictionary<Type, string> SetNames = new ConcurrentDictionary<Type, string>();
}

Ответы [ 2 ]

3 голосов
/ 06 января 2012

tmp может быть нулевым, если вы получаете что-то, кроме одного элемента, установленного из context.GetKeys(key).В этом случае keys.Count() != 1 и нулевой элемент будут вставлены в Cache.Keys для указанного ключа (и возвращены из GetOrAdd и присвоены tmp).

РЕДАКТИРОВАТЬ: Просто подумал о другой возможности.Какой тип данных является ключевым?Это какой-то пользовательский класс?Похоже, что это так.Если да, правильно ли вы реализовали Equals и GetHashcode?

0 голосов
/ 09 декабря 2013

Я должен был закрыть это некоторое время назад, но я полностью забыл об этом.Пример не является потокобезопасным из-за TryRemove, но он был добавлен только для целей отладки.В итоге я решил проблему, переписав ее, поэтому, возможно, некоторые комментарии о том, что код каким-то образом устарел, верны.Однако код для подтверждения больше не существует.

Я вычеркнул этот код из-за ошибки пользователя (мой собственный, конечно).Спасибо всем за время!

...