2010-02-17 18 views
6

Dado el seguimiento de pila:¿Cómo es posible esta excepción del diccionario <TKey, TValue>?

MESSAGE: Value cannot be null.Parameter name: key 
SOURCE: mscorlib 
TARGETSITE: Void ThrowArgumentNullException(System.ExceptionArgument) 
STACKTRACE: 
    at System.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument) 
    at System.Collections.Generic.Dictionary'2.FindEntry(TKey key) 
    at System.Collections.Generic.Dictionary'2.get_Item(TKey key) 
    at MyCompany.MAF.Agent.ServiceContracts.ConvertUtils.Convert(Dictionary'2 from) in D:\Development\MAF\Agent\MyCompany.MAF.Agent\ServiceContracts\ConvertUtils.cs:line 11 

llego a la conclusión de que de alguna manera el siguiente bloque de código se ha recuperado un nulo desde la entrada de la colección de llaves diccionario. Sin embargo, el diccionario de entrada es una instancia de Dictionary<string, string>. La implementación de Dictionary<string, string> hace que esa condición sea imposible. Al agregar un elemento con una clave nula, se lanza una excepción.

internal static KeyValuePair<string, string>[] Convert(IDictionary<string, string> from) 
{ 
    List<KeyValuePair<string, string>> ret = new List<KeyValuePair<string, string>>(); 
    foreach (string key in from.Keys) 
     ret.Add(new KeyValuePair<string, string>(key, from[key])); 
    return ret.ToArray(); 
} 
+0

Ya que realmente no responde su pregunta (mi mejor estimación es que está relacionada con el hilo)) pero su bucle es redundante from.ToArray() arrojará el mismo resultado –

Respuesta

11

He tenido este problema con frecuencia porque cometí el error de permitir que varios subprocesos accedan al mismo diccionario. Asegúrese de que este no sea el caso, porque Dictionary no es seguro para subprocesos.

(Por cierto, el método se puede simplificar en gran medida Dictionary<K,V> es ya un IEnumerable<KeyValuePair<K,V>> Usted debe ser capaz de simplemente hacer ToArray en una

+0

He intentado y no pude crear una condición de carrera con hilos Incluso si hubiera un problema de subprocesamiento, nunca sería posible que key se inicialice como nulo desde la colección Keys – goofballLogic

+0

Buen punto sobre el método ToArray: esto no explica la excepción, pero sospecho que evitará que ocurra. – goofballLogic

+0

No, no puede tener una clave nula, pero los métodos internos utilizados por 'Dictionary' aún pueden arrojar esta excepción al ingresar a ciertos estados. Lo he visto suceder mucho, especialmente cuando uso diccionarios estáticos no protegidos en mis aplicaciones ASP.NET. – Jacob

3

se parece más a que su argumento IDictionary tiene un elemento con un parámetro Key que es nulo.

La comprobación de parámetros para IDictionary probablemente se realice en algún lugar interno del marco.

+1

El diccionario no puede completarse con un elemento con una clave nula – goofballLogic

+0

@goofballogic, cierto, pero solo descubriría en tiempo de ejecución si su la cadena clave es nula y luego obtiene una excepción ... –

+1

No, el diccionario arroja una excepción si algo intenta llenarlo con una tecla nula. La excepción que se muestra es recuperar el valor, no agregarlo/insertarlo. – goofballLogic

2

Esta excepción se produce si la clave del diccionario es null. Como la clase incorporada Dictionary no permite dichas claves, puede estar utilizando su propia clase compatible IDictionary que permite null.

+0

No el diccionario pasado es un Diccionario goofballLogic

2

No estoy seguro sobre la hipótesis nula, pero por qué no estás usando:...

internal static KeyValuePair<string, string>[] Convert(IDictionary<string, string> from) 
{ 
    return from.ToArray(); 
} 

Editar:. en cuanto a los valores nulos se refiere ¿tiene múltiples hilos que accedan a este IDictionary la corrupción es posible si usted no está siendo seguro para subprocesos Ver este post para un ejemplo de la corrupción en el

?.
Queue<T> 

clase. How can I modify a queue collection in a loop?

+0

Buen punto: esto no explica la excepción, pero sospecho que evitará que suceda. – goofballLogic

+0

@goofballlogic: ver mi actualización. Si IDictionary se está volviendo corrupto, entonces simplificar el método podría no ser la solución.Es posible que deba implementar algún bloqueo alrededor de IDictionary. –

1

¿Podría ser posible que otro hilo esté afectando al dirctionary que se pasa en Convert?

1

Enlazar podría ser la causa, pero en este caso fue una pista falsa. También puede parecer tener este problema si tiene una versión Release compilación donde una función estaba en línea.Considere esto repro:

class Program 
{ 
    static string someKey = null; 

    static void Main(string[] args) 
    { 
     try 
     { 
      object thing; 

      if (SomeSeeminglyUnrelatedFunction(someKey, out thing)) Console.WriteLine("Found"); 

      things.TryGetValue(someKey, out thing); 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(ex.StackTrace.ToString()); 
      throw; 
     } 

     Console.ReadKey(); 
    } 

    private static Dictionary<string, object> stuff = new Dictionary<string, object>(); 
    private static Dictionary<string, object> things = new Dictionary<string, object>(); 

    private static bool SomeSeeminglyUnrelatedFunction(string key, out object item) 
    { 
     return stuff.TryGetValue(key, out item); 
    } 
} 

En mi máquina esto da la siguiente depuración acumulación Seguimiento de la pila:

at System.Collections.Generic.Dictionary`2.FindEntry(TKey key) 
at System.Collections.Generic.Dictionary`2.TryGetValue(TKey key, TValue& value) 
at MyApp.Program.SomeSeeminglyUnrelatedFunction(String key, Object& item) 
at MyApp.Program.Main(String[] args) 

Pero, da esta traza pila en lanzamiento construir:

at System.Collections.Generic.Dictionary`2.FindEntry(TKey key) 
at System.Collections.Generic.Dictionary`2.TryGetValue(TKey key, TValue& value) 
at MyApp.Program.Main(String[] args) 

Estaría tentado a pensar con esa última traza de pila que tiene que es things.TryGetValue que causa la excepción, cuando de hecho fue la función SomeSeeminglyUnrelatedFunction que se introdujo en Main.

Si aterrizas aquí, considera si tienes un problema similar. (Me doy cuenta de que esto puede no ser una respuesta directa a la pregunta de OP, pero quería compartir, no obstante, ya que podría ayudar a un visitante futuro)

Cuestiones relacionadas