2012-01-05 5 views
5

Bien, entonces me encuentro con un pequeño y extraño problema y, francamente, me he quedado sin ideas. Quería arrojar esto para ver si me estoy perdiendo algo que he hecho mal, o si ConcurrentDictionary no está funcionando correctamente. Aquí está el código:ConcurrentDictionary: ¿diccionario roto o código incorrecto?

(caché es una clase que contiene las claves ConcurrentDictionary estáticas)

El problema es que de vez en cuando tmp es null, haciendo que la línea de TryRemove para funcionar, sin embargo, la línea de return null; anterior no se ve afectado . Dado que return null es lo único que pone null en el diccionario y nunca se ejecuta, ¿cómo podría tmp ser alguna vez null?


Incluyendo la clase Cache (SetNames no es utilizado por el código):

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

¿Tal vez ya existe un valor 'nulo' en el diccionario? –

+0

¿Cuántos subprocesos ejecutan este código? No parece ser seguro para subprocesos. – oleksii

+0

@IlyaKogan - No, el diccionario está vacío cuando se inicia y nunca contiene un valor nulo, incluso cuando se golpea el punto de corte dentro de 'if (tmp == null)'. –

Respuesta

0

Debería haber cerrado esto hace un tiempo, pero me olvidé completamente de él. El ejemplo no es seguro para subprocesos debido a TryRemove, pero solo se agregó para fines de depuración. Terminé solucionando el problema reescribiéndolo, por lo que tal vez algunos de los comentarios sobre el código que de alguna manera están obsoletos son correctos. El código ya no existe para confirmar, sin embargo.

Lo atribuí a error del usuario (el mío, por supuesto). Gracias por el tiempo de todos!

3

tmp puede ser nulo si se obtiene más que un solo elemento situado detrás de context.GetKeys(key) nada. En ese caso, keys.Count() != 1, y un elemento nulo se insertará en Cache.Keys para la clave especificada (y se devolvió desde GetOrAdd, y se asignó al tmp).

EDIT: Pensé en otra posibilidad. ¿Qué tipo de datos es la clave? ¿Es algún tipo de clase personalizada? Parece que es. Si es así, ¿ha implementado Equals y GetHashcode correctamente?

+0

pero el OP indica que la línea 'return null' nunca se ejecuta, lo cual, si es correcto, significa que su escenario nunca ocurre. – phoog

+0

@phoog es correcto. También verifiqué dos veces los parámetros entrantes, así como 'context.GetKeys (key)' y ese caso no ocurrirá con estos datos. Espero que suceda en el futuro, pero ese no es el problema. –

+0

Entonces el OP está equivocado :-) O el diccionario contiene un nulo para la clave especificada, o se ejecuta la línea de retorno nulo. Ahora, de los nombres de las variables dudo sobre la llamada a GetOrAdd en el miembro ** Keys **, pero esa es otra historia. –

Cuestiones relacionadas