2012-01-05 4 views
5

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

(Cache представляет собой класс, содержащий статические ConcurrentDictionary ключи)

Проблема заключается в том, что иногда 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>(); 
} 
+0

Возможно, в словаре есть значение «null»? –

+0

Сколько потоков работает с этим кодом? Это не похоже на потокобезопасность. – oleksii

+0

@IlyaKogan - Нет, словарь пуст, когда он запускается и никогда не содержит нуль, даже когда попадает точка останова внутри 'if (tmp == null)'. –

ответ

0

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

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

3

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

EDIT: Просто подумал о другой возможности. Какой тип данных является ключом? Это какой-то пользовательский класс? Похоже, что так оно и есть. Если да, то внесли ли вы Equals и GetHashcode правильно?

+0

, но OP указывает, что строка «return null» никогда не выполняется, что, если правильно, означает, что ваш сценарий никогда не возникает. – phoog

+0

@phoog правильный - я также дважды проверял входящие параметры, а также 'context.GetKeys (key)', и этот случай не будет происходить с этими данными. Я ожидаю, что это произойдет в будущем, но это не проблема. –

+0

Тогда ОП ошибочно :-) Словарь содержит нуль для указанного ключа, или возвращает нулевую строку. Теперь из имен переменных я сомневаюсь в вызове GetOrAdd на члене ** Keys **, но это уже другая история. –