在我的应用程序中,几次ArgumentNullException
被抛出,但没有提供任何参数名称。这只发生在生产中(异常是在脚本服务中引发的,由javascript调用)。
我试图在StackTrace指向的代码片段中重现这种错误,但我能够重现的每个ArgumentNullException
在其消息中都包含一些参数名称。
所以,我的问题是,有人知道在没有提供参数名称的情况下抛出ArgumentNullException
的时间吗?或者什么方法最终会触发这个例外?
脚本服务是从应用程序缓存中获取一些信息:
private Dictionary<int, MyType> CachedDictionary
{
get
{
//return the Item from the application cache
return GetItem() as Dictionary<int, MyType>;
}
set
{
//adds the Item to the application cache
//with sliding expiration of X minutes
AddItem(value);
}
}
public List<MyType> Get(List<int> idsToRead)
{
List<int> idsNotCached = idsToRead.Except<int>(CachedDictionary.Keys.ToList<int>()).ToList<int>();
if (idsNotCached.Count > 0)
{
//Exception stack trace points to next line:
MyTypeCollection DBitems = BusinessLayer.StaticLoadFromDB(idsNotCached);
lock (CachedDictionary)
{
foreach (MyType item in DBitems)
if (!CachedDictionary.ContainsKey(item.ID))
CachedDictionary.Add(item.ID, item);
}
}
return CachedDictionary.Where(p => idsToRead.Contains(p.Key)).Select(p => p.Value).ToList<MyType>();
}
public static MyTypeCollection StaticLoadFromDB(List<int> ids)
{
try
{
//load from db...
}
catch (Exception e)
{
return HandleException<MyType>(e);
//returns MyTypeCollection with HasError set to TRUE and defined ErrorMessage
}
}
答案 0 :(得分:2)
没有代码,很难确定可能的原因。您可以尝试以下一般准则来尝试识别问题。
当未提供方法的参数时,通常会触发异常ArgumentNullException
。 ArgumentNullException
的构造函数不需要提供参数名称。有些方法只接受一个参数,因此不需要提供null参数的名称。
只需
即可在代码中的任何位置触发异常throw new ArgumentNullException();
为了帮助确定问题的原因,您需要查看堆栈跟踪,然后查看提供的参数。尝试确定当时正在尝试执行的操作,从而确定可能的参数值。
或者,您可以尝试添加try catch,以记录调用时发送给方法的可能值。例如,
try
{
FunctionThatThrowsArgumentNullException(myParameter);
} catch (ArgumentNullException ane)
{
Log.WriteLine("Argument Null Exception Raised", ane);
Log.WriteLine("Parameters supplied : {0}", myParameter);
throw; // Pass the exception on, as we are only logging
}
答案 1 :(得分:2)
ArgumentNullException是公共的,任何人都可以抛出此异常。您的同事或您使用的第三方图书馆可能会抛出它。
您必须通过查看异常中的堆栈跟踪来回答您自己的问题。这将告诉您抛出异常的位置,以及它之前的所有方法。
以此代码为例:
通过检查异常,您可以看到错误的来源。在堆栈顶部跟踪是抛出异常的方法,然后是导致它的方法调用链。
答案 2 :(得分:0)
如前所述,您没有使用任何第三方库,可能会在您自己的代码库中抛出异常。正如Kami解释的那样,引发此异常的代码可以标识为:
throw new ArgumentNullException();
为什么不在代码库中搜索此行?如果幸运的话,你会发现引发这个异常的地方而不传递参数名称!
答案 3 :(得分:0)
List<int> idsNotCached = idsToRead.Except<int>(CachedDictionary.Keys.ToList<int>()).ToList<int>();
(参见上面提供的代码示例)CachedDictionary已过期且在线:
lock (CachedDictionary)
抛出ArgumentNullException而不提供参数名称。显然我错过了测试这个锁。
通过一些额外的代码行解决问题:
public List<MyType> Get(List<int> idsToRead)
{
Dictionary<int, MyType> localCachedDictionary = CachedDictionary;
if (localCachedDictionary == null)
localCachedDictionary = new Dictionar<int, MyType>();
List<int> idsNotCached = idsToRead.Except<int>(localCachedDictionary.Keys.ToList<int>()).ToList<int>();
if (idsNotCached.Count > 0)
{
//Exception stack trace points to next line:
MyTypeCollection DBitems = BusinessLayer.StaticLoadFromDB(idsNotCached);
lock (localCachedDictionary)
{
foreach (MyType item in DBitems)
if (!localCachedDictionary.ContainsKey(item.ID))
localCachedDictionary.Add(item.ID, item);
}
}
if (CachedDictionary == null)
CachedDictionary = localCachedDictionary;
return localCachedDictionary.Where(p => idsToRead.Contains(p.Key)).Select(p => p.Value).ToList<MyType>();
}