1

在我的应用程序中抛出了几次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
    }
}
4

4 回答 4

2

没有代码,很难确定可能的原因。您可以尝试以下一般准则来尝试确定问题。

ArgumentNullException当未提供方法的参数时,通常会触发异常。构造函数ArgumentNullException不需要提供参数名称。有些方法只接受一个参数,因此不需要提供为空的参数名称。

只需简单地在代码中的任何位置触发异常

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
}
于 2013-09-20T10:13:51.543 回答
2

ArgumentNullException 是公共的,任何人都可以抛出此异常。可能是您的同事或您使用的第 3 方库抛出了它。

您必须通过查看异常中的堆栈跟踪来回答您自己的问题。这将告诉您异常在哪里引发,以及它之前的所有方法。

以这段代码为例: 在此处输入图像描述

通过检查异常,您可以看到错误来自何处。堆栈跟踪的顶部是引发异常的方法,然后是导致异常的方法调用链。 在此处输入图像描述

于 2013-09-20T10:17:17.273 回答
0

伙计们,非常感谢您的关注。
正如 Kami 建议的那样,我添加了一些额外的日志记录,幸运的是,异常被重现了,现在一切都清楚了。
似乎在这一行之后:

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>();
}
于 2013-10-14T08:27:38.880 回答
0

正如您所提到的,您没有使用任何 3rd 方库,异常可能是从您自己的代码库中抛出的。正如 Kami 解释的那样,引发此异常的代码可以标识为:

throw new ArgumentNullException();

你为什么不在你的代码库中搜索这一行?如果幸运的话,您会在不传递参数名称的情况下找到引发此异常的地方!

于 2013-09-20T11:14:00.997 回答