给出以下堆栈跟踪:
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
我得出结论,以下代码块以某种方式从输入Dictionary的Keys集合中检索了一个null。但是,输入字典是Dictionary<string, string>
的实例。 Dictionary<string, string>
的实现使得该条件无法实现。添加带有空键的项目后,将抛出异常。
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 :(得分:12)
我经常遇到这个问题,因为我错误地允许多个线程访问同一个字典。确保不是这种情况,因为Dictionary
不是线程安全的。
(顺便提一下,您的方法可以大大简化。Dictionary<K,V>
已经是IEnumerable<KeyValuePair<K,V>>
。您应该只能在ToArray
上进行操作。
答案 1 :(得分:3)
看起来更像是IDictionary
参数的参数为Key
的项目为空。
IDictionary
的参数检查可能会在框架内部的某处发生。
答案 2 :(得分:2)
如果字典键为null
,则会发生此异常。由于内置的Dictionary
类不允许使用此类密钥,因此您可能正在使用自己的IDictionary
兼容类,该类允许null
。
答案 3 :(得分:2)
不确定null,但为什么不使用:
internal static KeyValuePair<string, string>[] Convert(IDictionary<string, string> from)
{
return from.ToArray();
}
编辑:就空值而言。你有多个线程访问这个IDictionary?如果你不是线程安全的话,腐败是可能的。有关
中的损坏示例,请参阅此文章Queue<T>
答案 4 :(得分:2)
线程可能是原因,但在我们的案例中它是一个红色的鲱鱼。如果你有一个内联函数的发布版本,你也可以似乎来解决这个问题。考虑一下这个重复:
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);
}
}
在我的机器上,这提供了以下 Debug build 堆栈跟踪:
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)
但是,它在发布版本中提供此堆栈跟踪:
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)
你很想用最后一个堆栈跟踪认为它 是things.TryGetValue
导致异常,而实际上它是SomeSeeminglyUnrelatedFunction
函数在Main
内联。
所以如果你降落在这里,请考虑你是否有类似的问题。 (我意识到这可能不是OP问题的直接答案,但是希望分享,因为它可能有助于未来的访问者。)
答案 5 :(得分:1)
是否可能是另一个线程正在影响传递给Convert的dirctionary?